From 945063ea3011bc0fd5f309574450d1336eddeb0c Mon Sep 17 00:00:00 2001 From: Gehstock Date: Sun, 11 Feb 2018 08:33:46 +0100 Subject: [PATCH] add Vectrex --- GCE - Vectrex_MiST/README.TXT | 97 + GCE - Vectrex_MiST/Snapshot/vectrex_MiST.rbf | Bin 0 -> 256894 bytes GCE - Vectrex_MiST/clean.bat | 15 + GCE - Vectrex_MiST/rtl/YM2149_linmix_sep.vhd | 574 ++ GCE - Vectrex_MiST/rtl/build_id.tcl | 35 + GCE - Vectrex_MiST/rtl/build_id.v | 2 + GCE - Vectrex_MiST/rtl/card.qip | 3 + GCE - Vectrex_MiST/rtl/card.v | 177 + GCE - Vectrex_MiST/rtl/cpu09l_128a.vhd | 5946 +++++++++++++++++ GCE - Vectrex_MiST/rtl/dac.vhd | 71 + GCE - Vectrex_MiST/rtl/gen_ram.vhd | 84 + GCE - Vectrex_MiST/rtl/hq2x.sv | 454 ++ GCE - Vectrex_MiST/rtl/keyboard.v | 79 + GCE - Vectrex_MiST/rtl/m6522a.vhd | 903 +++ GCE - Vectrex_MiST/rtl/mist_io.v | 491 ++ GCE - Vectrex_MiST/rtl/osd.v | 179 + GCE - Vectrex_MiST/rtl/pll.qip | 4 + GCE - Vectrex_MiST/rtl/pll.v | 376 ++ GCE - Vectrex_MiST/rtl/scandoubler.v | 194 + GCE - Vectrex_MiST/rtl/vectrex.vhd | 805 +++ GCE - Vectrex_MiST/rtl/vectrex_exec_prom.vhd | 534 ++ GCE - Vectrex_MiST/rtl/vectrex_mist.sv | 179 + .../rtl/vectrex_scramble_prom.vhd | 278 + GCE - Vectrex_MiST/rtl/video_mixer.sv | 242 + .../binaries/linux32/duplicate_byte | Bin 0 -> 7356 bytes .../binaries/linux32/make_vhdl_prom | Bin 0 -> 11712 bytes .../binaries/win32/duplicate_byte.exe | Bin 0 -> 97353 bytes .../binaries/win32/make_vhdl_prom.exe | Bin 0 -> 100636 bytes .../binaries/win64/duplicate_byte.exe | Bin 0 -> 117095 bytes .../binaries/win64/make_vhdl_prom.exe | Bin 0 -> 119861 bytes .../tools_prom_src/src/doc_compilation.txt | 28 + .../tools/tools_prom_src/src/duplicate_byte.c | 37 + .../tools/tools_prom_src/src/make_vhdl_prom.c | 83 + .../vectrex_unzip/make_vectrex_proms.bat | 14 + .../tools/vectrex_unzip/make_vhdl_prom.exe | Bin 0 -> 119861 bytes GCE - Vectrex_MiST/vectrex_MiST.qpf | 31 + GCE - Vectrex_MiST/vectrex_MiST.qsf | 223 + GCE - Vectrex_MiST/vectrex_MiST.srf | 13 + 38 files changed, 12151 insertions(+) create mode 100644 GCE - Vectrex_MiST/README.TXT create mode 100644 GCE - Vectrex_MiST/Snapshot/vectrex_MiST.rbf create mode 100644 GCE - Vectrex_MiST/clean.bat create mode 100644 GCE - Vectrex_MiST/rtl/YM2149_linmix_sep.vhd create mode 100644 GCE - Vectrex_MiST/rtl/build_id.tcl create mode 100644 GCE - Vectrex_MiST/rtl/build_id.v create mode 100644 GCE - Vectrex_MiST/rtl/card.qip create mode 100644 GCE - Vectrex_MiST/rtl/card.v create mode 100644 GCE - Vectrex_MiST/rtl/cpu09l_128a.vhd create mode 100644 GCE - Vectrex_MiST/rtl/dac.vhd create mode 100644 GCE - Vectrex_MiST/rtl/gen_ram.vhd create mode 100644 GCE - Vectrex_MiST/rtl/hq2x.sv create mode 100644 GCE - Vectrex_MiST/rtl/keyboard.v create mode 100644 GCE - Vectrex_MiST/rtl/m6522a.vhd create mode 100644 GCE - Vectrex_MiST/rtl/mist_io.v create mode 100644 GCE - Vectrex_MiST/rtl/osd.v create mode 100644 GCE - Vectrex_MiST/rtl/pll.qip create mode 100644 GCE - Vectrex_MiST/rtl/pll.v create mode 100644 GCE - Vectrex_MiST/rtl/scandoubler.v create mode 100644 GCE - Vectrex_MiST/rtl/vectrex.vhd create mode 100644 GCE - Vectrex_MiST/rtl/vectrex_exec_prom.vhd create mode 100644 GCE - Vectrex_MiST/rtl/vectrex_mist.sv create mode 100644 GCE - Vectrex_MiST/rtl/vectrex_scramble_prom.vhd create mode 100644 GCE - Vectrex_MiST/rtl/video_mixer.sv create mode 100644 GCE - Vectrex_MiST/tools/tools_prom_src/binaries/linux32/duplicate_byte create mode 100644 GCE - Vectrex_MiST/tools/tools_prom_src/binaries/linux32/make_vhdl_prom create mode 100644 GCE - Vectrex_MiST/tools/tools_prom_src/binaries/win32/duplicate_byte.exe create mode 100644 GCE - Vectrex_MiST/tools/tools_prom_src/binaries/win32/make_vhdl_prom.exe create mode 100644 GCE - Vectrex_MiST/tools/tools_prom_src/binaries/win64/duplicate_byte.exe create mode 100644 GCE - Vectrex_MiST/tools/tools_prom_src/binaries/win64/make_vhdl_prom.exe create mode 100644 GCE - Vectrex_MiST/tools/tools_prom_src/src/doc_compilation.txt create mode 100644 GCE - Vectrex_MiST/tools/tools_prom_src/src/duplicate_byte.c create mode 100644 GCE - Vectrex_MiST/tools/tools_prom_src/src/make_vhdl_prom.c create mode 100644 GCE - Vectrex_MiST/tools/vectrex_unzip/make_vectrex_proms.bat create mode 100644 GCE - Vectrex_MiST/tools/vectrex_unzip/make_vhdl_prom.exe create mode 100644 GCE - Vectrex_MiST/vectrex_MiST.qpf create mode 100644 GCE - Vectrex_MiST/vectrex_MiST.qsf create mode 100644 GCE - Vectrex_MiST/vectrex_MiST.srf diff --git a/GCE - Vectrex_MiST/README.TXT b/GCE - Vectrex_MiST/README.TXT new file mode 100644 index 00000000..5fd3115f --- /dev/null +++ b/GCE - Vectrex_MiST/README.TXT @@ -0,0 +1,97 @@ + +GCE(General Consumer Electronics) - Vectrex For Mist FPGA + +Controls: + Movement: Joystick, Keyboard(Arrow Keys) + Buttons: 1-2 on Joystick Fire Buttons + 1-4 on Keyboard 1-4 + +ToDo: Fix Rom Loader + + + + +--------------------------------------------------------------------------------- +-- DE10_lite Top level for vectrex by Dar (darfpga@aol.fr) (27/12/2017) +-- http://darfpga.blogspot.fr +--------------------------------------------------------------------------------- +-- Educational use only +-- Do not redistribute synthetized file with roms +-- Do not redistribute roms whatever the form +-- Use at your own risk +--------------------------------------------------------------------------------- +-- Use vectrex_de10_lite.sdc to compile (Timequest constraints) +-- /!\ +-- Don't forget to set device configuration mode with memory initialization +-- (Assignments/Device/Pin options/Configuration mode) +--------------------------------------------------------------------------------- +-- TODO : +-- sligt tune of characters drawings (too wide) +-- tune hblank to avoid persistance artifact on first 4 pixels of a line +--------------------------------------------------------------------------------- +-- +-- Main features : +-- PS2 keyboard input @gpio pins 35/34 (beware voltage translation/protection) +-- Audio pwm output @gpio pins 1/3 (beware voltage translation/protection) +-- +-- Uses 1 pll for 25/24MHz and 12.5/12MHz generation from 50MHz +-- +-- Horizontal/vertical display selection at compilation +-- 3 or no intensity level selection at compilation +-- +-- No external ram +-- FPGA ram usage as low as : +-- +-- 336.000b ( 42Ko) without cartridge, vertical display, no intensity level (minestrom) +-- 402.000b ( 50Ko) with 8Ko cartridge, vertical display, no intensity level +-- 599.000b ( 74ko) with 32Ko cartridge, vertical display, no intensity level +-- 664.000b ( 82ko) with 8Ko cartridge, horizontal display, no intensity level +-- 1.188.000b (146ko) with 8Ko cartridge, horizontal display, 3 intensity level + +-- Tested cartridge: +-- +-- berzerk ( 4ko) +-- ripoff ( 4ko) +-- scramble ( 4ko) +-- spacewar ( 4ko) +-- startrek ( 4ko) +-- pole position ( 8ko) +-- spike ( 8ko) +-- webwars ( 8ko) +-- frogger (16Ko) +-- vecmania1 (32ko) +-- war of the robot (21ko) +-- +-- Board key : +-- 0 : reset game +-- +-- Keyboard players inputs : +-- +-- F3 : button +-- F2 : button +-- F1 : button +-- SPACE : button +-- RIGHT arrow : joystick right +-- LEFT arrow : joystick left +-- UP arrow : joystick up +-- DOWN arrow : joystick down +-- +-- Other details : see vectrex.vhd +-- For USB inputs and SGT5000 audio output see my other project: xevious_de10_lite +--------------------------------------------------------------------------------- +-- Use tool\vectrex_unzip\make_vectrex_proms.bat to build vhdl rom files +-- +--make_vhdl_prom exec_rom.bin vectrex_exec_prom.vhd (always needed) +-- +--make_vhdl_prom scramble.bin vectrex_scramble_prom.vhd +--make_vhdl_prom berzerk.bin vectrex_berzerk_prom.vhd +--make_vhdl_prom frogger.bin vectrex_frogger_prom.vhd +--make_vhdl_prom spacewar.bin vectrex_spacewar_prom.vhd +--make_vhdl_prom polepos.bin vectrex_polepos_prom.vhd +--make_vhdl_prom ripoff.bin vectrex_ripoff_prom.vhd +--make_vhdl_prom spike.bin vectrex_spike_prom.vhd +--make_vhdl_prom startrek.bin vectrex_startrek_prom.vhd +--make_vhdl_prom vecmania1.bin vectrex_vecmania1_prom.vhd +--make_vhdl_prom webwars.bin vectrex_webwars_prom.vhd +--make_vhdl_prom wotr.bin vectrex_wotr_prom.vhd +--------------------------------------------------------------------------------- diff --git a/GCE - Vectrex_MiST/Snapshot/vectrex_MiST.rbf b/GCE - Vectrex_MiST/Snapshot/vectrex_MiST.rbf new file mode 100644 index 0000000000000000000000000000000000000000..c8a478a59133d570a71211f59f020b4cd38c741d GIT binary patch literal 256894 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 VV0I;>CiJxa(E0pJpINo={{um4e-i)z literal 0 HcmV?d00001 diff --git a/GCE - Vectrex_MiST/clean.bat b/GCE - Vectrex_MiST/clean.bat new file mode 100644 index 00000000..83fb0c47 --- /dev/null +++ b/GCE - Vectrex_MiST/clean.bat @@ -0,0 +1,15 @@ +@echo off +del /s *.bak +del /s *.orig +del /s *.rej +rmdir /s /q db +rmdir /s /q incremental_db +rmdir /s /q output_files +rmdir /s /q simulation +rmdir /s /q greybox_tmp +del PLLJ_PLLSPE_INFO.txt +del *.qws +del *.ppf +del *.qip +del *.ddb +pause diff --git a/GCE - Vectrex_MiST/rtl/YM2149_linmix_sep.vhd b/GCE - Vectrex_MiST/rtl/YM2149_linmix_sep.vhd new file mode 100644 index 00000000..6ed2498a --- /dev/null +++ b/GCE - Vectrex_MiST/rtl/YM2149_linmix_sep.vhd @@ -0,0 +1,574 @@ +-- changes for seperate audio outputs and enable now enables cpu access as well +-- +-- A simulation model of YM2149 (AY-3-8910 with bells on) + +-- Copyright (c) MikeJ - Jan 2005 +-- +-- 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. +-- +-- You are responsible for any legal issues arising from your use of this code. +-- +-- The latest version of this file can be found at: www.fpgaarcade.com +-- +-- Email support@fpgaarcade.com +-- +-- Revision list +-- +-- version 001 initial release +-- +-- Clues from MAME sound driver and Kazuhiro TSUJIKAWA +-- +-- These are the measured outputs from a real chip for a single Isolated channel into a 1K load (V) +-- vol 15 .. 0 +-- 3.27 2.995 2.741 2.588 2.452 2.372 2.301 2.258 2.220 2.198 2.178 2.166 2.155 2.148 2.141 2.132 +-- As the envelope volume is 5 bit, I have fitted a curve to the not quite log shape in order +-- to produced all the required values. +-- (The first part of the curve is a bit steeper and the last bit is more linear than expected) +-- +-- NOTE, this component uses LINEAR mixing of the three analogue channels, and is only +-- accurate for designs where the outputs are buffered and not simply wired together. +-- The ouput level is more complex in that case and requires a larger table. + +library ieee; + use ieee.std_logic_1164.all; + use ieee.std_logic_arith.all; + use ieee.std_logic_unsigned.all; + +entity YM2149 is + port ( + -- data bus + I_DA : in std_logic_vector(7 downto 0); + O_DA : out std_logic_vector(7 downto 0); + O_DA_OE_L : out std_logic; + -- control + I_A9_L : in std_logic; + I_A8 : in std_logic; + I_BDIR : in std_logic; + I_BC2 : in std_logic; + I_BC1 : in std_logic; + I_SEL_L : in std_logic; + + O_AUDIO : out std_logic_vector(7 downto 0); + O_CHAN : out std_logic_vector(1 downto 0); + -- port a + I_IOA : in std_logic_vector(7 downto 0); + O_IOA : out std_logic_vector(7 downto 0); + O_IOA_OE_L : out std_logic; + -- port b + I_IOB : in std_logic_vector(7 downto 0); + O_IOB : out std_logic_vector(7 downto 0); + O_IOB_OE_L : out std_logic; + + ENA : in std_logic; -- clock enable for higher speed operation + RESET_L : in std_logic; + CLK : in std_logic -- note 6 Mhz + ); +end; + +architecture RTL of YM2149 is + type array_16x8 is array (0 to 15) of std_logic_vector( 7 downto 0); + type array_3x12 is array (1 to 3) of std_logic_vector(11 downto 0); + + signal cnt_div : std_logic_vector(3 downto 0) := (others => '0'); + signal cnt_div_t1 : std_logic_vector(3 downto 0); + signal noise_div : std_logic := '0'; + signal ena_div : std_logic; + signal ena_div_noise : std_logic; + signal poly17 : std_logic_vector(16 downto 0) := (others => '0'); + + -- registers + signal addr : std_logic_vector(7 downto 0); + signal busctrl_addr : std_logic; + signal busctrl_we : std_logic; + signal busctrl_re : std_logic; + + signal reg : array_16x8; + signal env_reset : std_logic; + signal ioa_inreg : std_logic_vector(7 downto 0); + signal iob_inreg : std_logic_vector(7 downto 0); + + signal noise_gen_cnt : std_logic_vector(4 downto 0); + signal noise_gen_op : std_logic; + signal tone_gen_cnt : array_3x12 := (others => (others => '0')); + signal tone_gen_op : std_logic_vector(3 downto 1) := "000"; + + signal env_gen_cnt : std_logic_vector(15 downto 0); + signal env_ena : std_logic; + signal env_hold : std_logic; + signal env_inc : std_logic; + signal env_vol : std_logic_vector(4 downto 0); + + signal tone_ena_l : std_logic; + signal tone_src : std_logic; + signal noise_ena_l : std_logic; + signal chan_vol : std_logic_vector(4 downto 0); + + signal dac_amp : std_logic_vector(7 downto 0); +begin + -- cpu i/f + p_busdecode : process(I_BDIR, I_BC2, I_BC1, addr, I_A9_L, I_A8) + variable cs : std_logic; + variable sel : std_logic_vector(2 downto 0); + begin + -- BDIR BC2 BC1 MODE + -- 0 0 0 inactive + -- 0 0 1 address + -- 0 1 0 inactive + -- 0 1 1 read + -- 1 0 0 address + -- 1 0 1 inactive + -- 1 1 0 write + -- 1 1 1 read + busctrl_addr <= '0'; + busctrl_we <= '0'; + busctrl_re <= '0'; + + cs := '0'; + if (I_A9_L = '0') and (I_A8 = '1') and (addr(7 downto 4) = "0000") then + cs := '1'; + end if; + + sel := (I_BDIR & I_BC2 & I_BC1); + case sel is + when "000" => null; + when "001" => busctrl_addr <= '1'; + when "010" => null; + when "011" => busctrl_re <= cs; + when "100" => busctrl_addr <= '1'; + when "101" => null; + when "110" => busctrl_we <= cs; + when "111" => busctrl_addr <= '1'; + when others => null; + end case; + end process; + + p_oe : process(busctrl_re) + begin + -- if we are emulating a real chip, maybe clock this to fake up the tristate typ delay of 100ns + O_DA_OE_L <= not (busctrl_re); + end process; + + -- + -- CLOCKED + -- + p_waddr : process(RESET_L, CLK) + begin + -- looks like registers are latches in real chip, but the address is caught at the end of the address state. + if (RESET_L = '0') then + addr <= (others => '0'); + elsif rising_edge(CLK) then + if (ENA = '1') then + if (busctrl_addr = '1') then + addr <= I_DA; + end if; + end if; + end if; + end process; + + p_wdata : process(RESET_L, CLK) + begin + if (RESET_L = '0') then + reg <= (others => (others => '0')); + env_reset <= '1'; + elsif rising_edge(CLK) then + if (ENA = '1') then + env_reset <= '0'; + if (busctrl_we = '1') then + case addr(3 downto 0) is + when x"0" => reg(0) <= I_DA; + when x"1" => reg(1) <= I_DA; + when x"2" => reg(2) <= I_DA; + when x"3" => reg(3) <= I_DA; + when x"4" => reg(4) <= I_DA; + when x"5" => reg(5) <= I_DA; + when x"6" => reg(6) <= I_DA; + when x"7" => reg(7) <= I_DA; + when x"8" => reg(8) <= I_DA; + when x"9" => reg(9) <= I_DA; + when x"A" => reg(10) <= I_DA; + when x"B" => reg(11) <= I_DA; + when x"C" => reg(12) <= I_DA; + when x"D" => reg(13) <= I_DA; env_reset <= '1'; + when x"E" => reg(14) <= I_DA; + when x"F" => reg(15) <= I_DA; + when others => null; + end case; + end if; + end if; + end if; + end process; + + p_rdata : process(busctrl_re, addr, reg, ioa_inreg, iob_inreg) + begin + O_DA <= (others => '0'); -- 'X' + if (busctrl_re = '1') then -- not necessary, but useful for putting 'X's in the simulator + case addr(3 downto 0) is + when x"0" => O_DA <= reg(0) ; + when x"1" => O_DA <= "0000" & reg(1)(3 downto 0) ; + when x"2" => O_DA <= reg(2) ; + when x"3" => O_DA <= "0000" & reg(3)(3 downto 0) ; + when x"4" => O_DA <= reg(4) ; + when x"5" => O_DA <= "0000" & reg(5)(3 downto 0) ; + when x"6" => O_DA <= "000" & reg(6)(4 downto 0) ; + when x"7" => O_DA <= reg(7) ; + when x"8" => O_DA <= "000" & reg(8)(4 downto 0) ; + when x"9" => O_DA <= "000" & reg(9)(4 downto 0) ; + when x"A" => O_DA <= "000" & reg(10)(4 downto 0) ; + when x"B" => O_DA <= reg(11); + when x"C" => O_DA <= reg(12); + when x"D" => O_DA <= "0000" & reg(13)(3 downto 0); + when x"E" => if (reg(7)(6) = '0') then -- input + O_DA <= ioa_inreg; + else + O_DA <= reg(14); -- read output reg + end if; + when x"F" => if (Reg(7)(7) = '0') then + O_DA <= iob_inreg; + else + O_DA <= reg(15); + end if; + when others => null; + end case; + end if; + end process; + -- + p_divider : process + begin + wait until rising_edge(CLK); + -- / 8 when SEL is high and /16 when SEL is low + if (ENA = '1') then + ena_div <= '0'; + ena_div_noise <= '0'; + if (cnt_div = "0000") then + cnt_div <= (not I_SEL_L) & "111"; + ena_div <= '1'; + + noise_div <= not noise_div; + if (noise_div = '1') then + ena_div_noise <= '1'; + end if; + else + cnt_div <= cnt_div - "1"; + end if; + end if; + end process; + + p_noise_gen : process + variable noise_gen_comp : std_logic_vector(4 downto 0); + variable poly17_zero : std_logic; + begin + wait until rising_edge(CLK); + if (reg(6)(4 downto 0) = "00000") then + noise_gen_comp := "00000"; + else + noise_gen_comp := (reg(6)(4 downto 0) - "1"); + end if; + + poly17_zero := '0'; + if (poly17 = "00000000000000000") then poly17_zero := '1'; end if; + + if (ENA = '1') then + if (ena_div_noise = '1') then -- divider ena + + if (noise_gen_cnt >= noise_gen_comp) then + noise_gen_cnt <= "00000"; + poly17 <= (poly17(0) xor poly17(2) xor poly17_zero) & poly17(16 downto 1); + else + noise_gen_cnt <= (noise_gen_cnt + "1"); + end if; + end if; + end if; + end process; + noise_gen_op <= poly17(0); + + p_tone_gens : process + variable tone_gen_freq : array_3x12; + variable tone_gen_comp : array_3x12; + begin + wait until rising_edge(CLK); + -- looks like real chips count up - we need to get the Exact behaviour .. + tone_gen_freq(1) := reg(1)(3 downto 0) & reg(0); + tone_gen_freq(2) := reg(3)(3 downto 0) & reg(2); + tone_gen_freq(3) := reg(5)(3 downto 0) & reg(4); + -- period 0 = period 1 + for i in 1 to 3 loop + if (tone_gen_freq(i) = x"000") then + tone_gen_comp(i) := x"000"; + else + tone_gen_comp(i) := (tone_gen_freq(i) - "1"); + end if; + end loop; + + if (ENA = '1') then + for i in 1 to 3 loop + if (ena_div = '1') then -- divider ena + + if (tone_gen_cnt(i) >= tone_gen_comp(i)) then + tone_gen_cnt(i) <= x"000"; + tone_gen_op(i) <= not tone_gen_op(i); + else + tone_gen_cnt(i) <= (tone_gen_cnt(i) + "1"); + end if; + end if; + end loop; + end if; + end process; + + p_envelope_freq : process + variable env_gen_freq : std_logic_vector(15 downto 0); + variable env_gen_comp : std_logic_vector(15 downto 0); + begin + wait until rising_edge(CLK); + env_gen_freq := reg(12) & reg(11); + -- envelope freqs 1 and 0 are the same. + if (env_gen_freq = x"0000") then + env_gen_comp := x"0000"; + else + env_gen_comp := (env_gen_freq - "1"); + end if; + + if (ENA = '1') then + env_ena <= '0'; + if (ena_div = '1') then -- divider ena + if (env_gen_cnt >= env_gen_comp) then + env_gen_cnt <= x"0000"; + env_ena <= '1'; + else + env_gen_cnt <= (env_gen_cnt + "1"); + end if; + end if; + end if; + end process; + + p_envelope_shape : process(env_reset, reg, CLK) + variable is_bot : boolean; + variable is_bot_p1 : boolean; + variable is_top_m1 : boolean; + variable is_top : boolean; + begin + -- 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 = '1') then + -- load initial state + if (reg(13)(2) = '0') then -- attack + env_vol <= "11111"; + env_inc <= '0'; -- -1 + else + env_vol <= "00000"; + env_inc <= '1'; -- +1 + end if; + env_hold <= '0'; + + elsif rising_edge(CLK) then + is_bot := (env_vol = "00000"); + is_bot_p1 := (env_vol = "00001"); + is_top_m1 := (env_vol = "11110"); + is_top := (env_vol = "11111"); + + if (ENA = '1') then + if (env_ena = '1') then + if (env_hold = '0') then + if (env_inc = '1') then + env_vol <= (env_vol + "00001"); + else + env_vol <= (env_vol + "11111"); + end if; + end if; + + -- envelope shape control. + if (reg(13)(3) = '0') then + if (env_inc = '0') then -- down + if is_bot_p1 then env_hold <= '1'; end if; + else + if is_top then env_hold <= '1'; end if; + end if; + else + if (reg(13)(0) = '1') then -- hold = 1 + if (env_inc = '0') then -- down + if (reg(13)(1) = '1') then -- alt + if is_bot then env_hold <= '1'; end if; + else + if is_bot_p1 then env_hold <= '1'; end if; + end if; + else + if (reg(13)(1) = '1') then -- alt + if is_top then env_hold <= '1'; end if; + else + if is_top_m1 then env_hold <= '1'; end if; + end if; + end if; + + elsif (reg(13)(1) = '1') then -- alternate + if (env_inc = '0') then -- down + if is_bot_p1 then env_hold <= '1'; end if; + if is_bot then env_hold <= '0'; env_inc <= '1'; end if; + else + if is_top_m1 then env_hold <= '1'; end if; + if is_top then env_hold <= '0'; env_inc <= '0'; end if; + end if; + end if; + + end if; + end if; + end if; + end if; + end process; + + p_chan_mixer : process(cnt_div, reg, tone_gen_op) + begin + tone_ena_l <= '1'; tone_src <= '1'; + noise_ena_l <= '1'; chan_vol <= "00000"; + case cnt_div(1 downto 0) is + when "00" => + tone_ena_l <= reg(7)(0); tone_src <= tone_gen_op(1); chan_vol <= reg(8)(4 downto 0); + noise_ena_l <= reg(7)(3); + when "01" => + tone_ena_l <= reg(7)(1); tone_src <= tone_gen_op(2); chan_vol <= reg(9)(4 downto 0); + noise_ena_l <= reg(7)(4); + when "10" => + tone_ena_l <= reg(7)(2); tone_src <= tone_gen_op(3); chan_vol <= reg(10)(4 downto 0); + noise_ena_l <= reg(7)(5); + when "11" => null; -- tone gen outputs become valid on this clock + when others => null; + end case; + end process; + + p_op_mixer : process + variable chan_mixed : std_logic; + variable chan_amp : std_logic_vector(4 downto 0); + begin + wait until rising_edge(CLK); + if (ENA = '1') then + + chan_mixed := (tone_ena_l or tone_src) and (noise_ena_l or noise_gen_op); + + chan_amp := (others => '0'); + if (chan_mixed = '1') then + if (chan_vol(4) = '0') then + if (chan_vol(3 downto 0) = "0000") then -- nothing is easy ! make sure quiet is quiet + chan_amp := "00000"; + else + chan_amp := chan_vol(3 downto 0) & '1'; -- make sure level 31 (env) = level 15 (tone) + end if; + else + chan_amp := env_vol(4 downto 0); + end if; + end if; + + dac_amp <= x"00"; + case chan_amp is + when "11111" => dac_amp <= x"FF"; + when "11110" => dac_amp <= x"D9"; + when "11101" => dac_amp <= x"BA"; + when "11100" => dac_amp <= x"9F"; + when "11011" => dac_amp <= x"88"; + when "11010" => dac_amp <= x"74"; + when "11001" => dac_amp <= x"63"; + when "11000" => dac_amp <= x"54"; + when "10111" => dac_amp <= x"48"; + when "10110" => dac_amp <= x"3D"; + when "10101" => dac_amp <= x"34"; + when "10100" => dac_amp <= x"2C"; + when "10011" => dac_amp <= x"25"; + when "10010" => dac_amp <= x"1F"; + when "10001" => dac_amp <= x"1A"; + when "10000" => dac_amp <= x"16"; + when "01111" => dac_amp <= x"13"; + when "01110" => dac_amp <= x"10"; + when "01101" => dac_amp <= x"0D"; + when "01100" => dac_amp <= x"0B"; + when "01011" => dac_amp <= x"09"; + when "01010" => dac_amp <= x"08"; + when "01001" => dac_amp <= x"07"; + when "01000" => dac_amp <= x"06"; + when "00111" => dac_amp <= x"05"; + when "00110" => dac_amp <= x"04"; + when "00101" => dac_amp <= x"03"; + when "00100" => dac_amp <= x"03"; + when "00011" => dac_amp <= x"02"; + when "00010" => dac_amp <= x"02"; + when "00001" => dac_amp <= x"01"; + when "00000" => dac_amp <= x"00"; + when others => null; + end case; + + cnt_div_t1 <= cnt_div; + end if; + end process; + + p_audio_output : process(RESET_L, CLK) + begin + if (RESET_L = '0') then + O_AUDIO <= (others => '0'); + O_CHAN <= (others => '0'); + elsif rising_edge(CLK) then + + if (ENA = '1') then + O_AUDIO <= dac_amp(7 downto 0); + O_CHAN <= cnt_div_t1(1 downto 0); + end if; + end if; + end process; + + p_io_ports : process(reg) + begin + O_IOA <= reg(14); + O_IOA_OE_L <= not reg(7)(6); + O_IOB <= reg(15); + O_IOB_OE_L <= not reg(7)(7); + end process; + + p_io_ports_inreg : process + begin + wait until rising_edge(CLK); + if (ENA = '1') then -- resync + ioa_inreg <= I_IOA; + iob_inreg <= I_IOB; + end if; + end process; +end architecture RTL; diff --git a/GCE - Vectrex_MiST/rtl/build_id.tcl b/GCE - Vectrex_MiST/rtl/build_id.tcl new file mode 100644 index 00000000..938515d8 --- /dev/null +++ b/GCE - Vectrex_MiST/rtl/build_id.tcl @@ -0,0 +1,35 @@ +# ================================================================================ +# +# Build ID Verilog Module Script +# Jeff Wiencrot - 8/1/2011 +# +# Generates a Verilog module that contains a timestamp, +# from the current build. These values are available from the build_date, build_time, +# physical_address, and host_name output ports of the build_id module in the build_id.v +# Verilog source file. +# +# ================================================================================ + +proc generateBuildID_Verilog {} { + + # Get the timestamp (see: http://www.altera.com/support/examples/tcl/tcl-date-time-stamp.html) + set buildDate [ clock format [ clock seconds ] -format %y%m%d ] + set buildTime [ clock format [ clock seconds ] -format %H%M%S ] + + # Create a Verilog file for output + set outputFileName "rtl/build_id.v" + set outputFile [open $outputFileName "w"] + + # Output the Verilog source + puts $outputFile "`define BUILD_DATE \"$buildDate\"" + puts $outputFile "`define BUILD_TIME \"$buildTime\"" + close $outputFile + + # Send confirmation message to the Messages window + post_message "Generated build identification Verilog module: [pwd]/$outputFileName" + post_message "Date: $buildDate" + post_message "Time: $buildTime" +} + +# Comment out this line to prevent the process from automatically executing when the file is sourced: +generateBuildID_Verilog \ No newline at end of file diff --git a/GCE - Vectrex_MiST/rtl/build_id.v b/GCE - Vectrex_MiST/rtl/build_id.v new file mode 100644 index 00000000..c9d3f3e7 --- /dev/null +++ b/GCE - Vectrex_MiST/rtl/build_id.v @@ -0,0 +1,2 @@ +`define BUILD_DATE "180211" +`define BUILD_TIME "074838" diff --git a/GCE - Vectrex_MiST/rtl/card.qip b/GCE - Vectrex_MiST/rtl/card.qip new file mode 100644 index 00000000..53989c71 --- /dev/null +++ b/GCE - Vectrex_MiST/rtl/card.qip @@ -0,0 +1,3 @@ +set_global_assignment -name IP_TOOL_NAME "RAM: 1-PORT" +set_global_assignment -name IP_TOOL_VERSION "13.1" +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "card.v"] diff --git a/GCE - Vectrex_MiST/rtl/card.v b/GCE - Vectrex_MiST/rtl/card.v new file mode 100644 index 00000000..b0d8bc34 --- /dev/null +++ b/GCE - Vectrex_MiST/rtl/card.v @@ -0,0 +1,177 @@ +// megafunction wizard: %RAM: 1-PORT% +// GENERATION: STANDARD +// VERSION: WM1.0 +// MODULE: altsyncram + +// ============================================================ +// File Name: card.v +// Megafunction Name(s): +// altsyncram +// +// Simulation Library Files(s): +// altera_mf +// ============================================================ +// ************************************************************ +// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE! +// +// 13.1.0 Build 162 10/23/2013 SJ Web Edition +// ************************************************************ + + +//Copyright (C) 1991-2013 Altera Corporation +//Your use of Altera Corporation's design tools, logic functions +//and other software and tools, and its AMPP partner logic +//functions, and any output files from any of the foregoing +//(including device programming or simulation files), and any +//associated documentation or information are expressly subject +//to the terms and conditions of the Altera Program License +//Subscription Agreement, Altera MegaCore Function License +//Agreement, or other applicable license agreement, including, +//without limitation, that your use is for the sole purpose of +//programming logic devices manufactured by Altera and sold by +//Altera or its authorized distributors. Please refer to the +//applicable agreement for further details. + + +// synopsys translate_off +`timescale 1 ps / 1 ps +// synopsys translate_on +module card ( + address, + clock, + data, + rden, + wren, + q); + + input [13:0] address; + input clock; + input [7:0] data; + input rden; + input wren; + output [7:0] q; +`ifndef ALTERA_RESERVED_QIS +// synopsys translate_off +`endif + tri1 clock; + tri1 rden; +`ifndef ALTERA_RESERVED_QIS +// synopsys translate_on +`endif + + wire [7:0] sub_wire0; + wire [7:0] q = sub_wire0[7:0]; + + altsyncram altsyncram_component ( + .address_a (address), + .clock0 (clock), + .data_a (data), + .wren_a (wren), + .rden_a (rden), + .q_a (sub_wire0), + .aclr0 (1'b0), + .aclr1 (1'b0), + .address_b (1'b1), + .addressstall_a (1'b0), + .addressstall_b (1'b0), + .byteena_a (1'b1), + .byteena_b (1'b1), + .clock1 (1'b1), + .clocken0 (1'b1), + .clocken1 (1'b1), + .clocken2 (1'b1), + .clocken3 (1'b1), + .data_b (1'b1), + .eccstatus (), + .q_b (), + .rden_b (1'b1), + .wren_b (1'b0)); + defparam + altsyncram_component.clock_enable_input_a = "BYPASS", + altsyncram_component.clock_enable_output_a = "BYPASS", + altsyncram_component.intended_device_family = "Cyclone III", + altsyncram_component.lpm_hint = "ENABLE_RUNTIME_MOD=NO", + altsyncram_component.lpm_type = "altsyncram", + altsyncram_component.numwords_a = 16384, + altsyncram_component.operation_mode = "SINGLE_PORT", + altsyncram_component.outdata_aclr_a = "NONE", + altsyncram_component.outdata_reg_a = "CLOCK0", + altsyncram_component.power_up_uninitialized = "FALSE", + altsyncram_component.read_during_write_mode_port_a = "NEW_DATA_NO_NBE_READ", + altsyncram_component.widthad_a = 14, + altsyncram_component.width_a = 8, + altsyncram_component.width_byteena_a = 1; + + +endmodule + +// ============================================================ +// CNX file retrieval info +// ============================================================ +// Retrieval info: PRIVATE: ADDRESSSTALL_A NUMERIC "0" +// Retrieval info: PRIVATE: AclrAddr NUMERIC "0" +// Retrieval info: PRIVATE: AclrByte NUMERIC "0" +// Retrieval info: PRIVATE: AclrData NUMERIC "0" +// Retrieval info: PRIVATE: AclrOutput NUMERIC "0" +// Retrieval info: PRIVATE: BYTE_ENABLE NUMERIC "0" +// Retrieval info: PRIVATE: BYTE_SIZE NUMERIC "8" +// Retrieval info: PRIVATE: BlankMemory NUMERIC "1" +// Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_A NUMERIC "0" +// Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_A NUMERIC "0" +// Retrieval info: PRIVATE: Clken NUMERIC "0" +// Retrieval info: PRIVATE: DataBusSeparated NUMERIC "1" +// Retrieval info: PRIVATE: IMPLEMENT_IN_LES NUMERIC "0" +// Retrieval info: PRIVATE: INIT_FILE_LAYOUT STRING "PORT_A" +// Retrieval info: PRIVATE: INIT_TO_SIM_X NUMERIC "0" +// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone III" +// Retrieval info: PRIVATE: JTAG_ENABLED NUMERIC "0" +// Retrieval info: PRIVATE: JTAG_ID STRING "NONE" +// Retrieval info: PRIVATE: MAXIMUM_DEPTH NUMERIC "0" +// Retrieval info: PRIVATE: MIFfilename STRING "" +// Retrieval info: PRIVATE: NUMWORDS_A NUMERIC "16384" +// Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0" +// Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_A NUMERIC "3" +// Retrieval info: PRIVATE: RegAddr NUMERIC "1" +// Retrieval info: PRIVATE: RegData NUMERIC "1" +// Retrieval info: PRIVATE: RegOutput NUMERIC "1" +// Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0" +// Retrieval info: PRIVATE: SingleClock NUMERIC "1" +// Retrieval info: PRIVATE: UseDQRAM NUMERIC "1" +// Retrieval info: PRIVATE: WRCONTROL_ACLR_A NUMERIC "0" +// Retrieval info: PRIVATE: WidthAddr NUMERIC "14" +// Retrieval info: PRIVATE: WidthData NUMERIC "8" +// Retrieval info: PRIVATE: rden NUMERIC "1" +// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all +// Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_A STRING "BYPASS" +// Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_A STRING "BYPASS" +// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone III" +// Retrieval info: CONSTANT: LPM_HINT STRING "ENABLE_RUNTIME_MOD=NO" +// Retrieval info: CONSTANT: LPM_TYPE STRING "altsyncram" +// Retrieval info: CONSTANT: NUMWORDS_A NUMERIC "16384" +// Retrieval info: CONSTANT: OPERATION_MODE STRING "SINGLE_PORT" +// Retrieval info: CONSTANT: OUTDATA_ACLR_A STRING "NONE" +// Retrieval info: CONSTANT: OUTDATA_REG_A STRING "CLOCK0" +// Retrieval info: CONSTANT: POWER_UP_UNINITIALIZED STRING "FALSE" +// Retrieval info: CONSTANT: READ_DURING_WRITE_MODE_PORT_A STRING "NEW_DATA_NO_NBE_READ" +// Retrieval info: CONSTANT: WIDTHAD_A NUMERIC "14" +// Retrieval info: CONSTANT: WIDTH_A NUMERIC "8" +// Retrieval info: CONSTANT: WIDTH_BYTEENA_A NUMERIC "1" +// Retrieval info: USED_PORT: address 0 0 14 0 INPUT NODEFVAL "address[13..0]" +// Retrieval info: USED_PORT: clock 0 0 0 0 INPUT VCC "clock" +// Retrieval info: USED_PORT: data 0 0 8 0 INPUT NODEFVAL "data[7..0]" +// Retrieval info: USED_PORT: q 0 0 8 0 OUTPUT NODEFVAL "q[7..0]" +// Retrieval info: USED_PORT: rden 0 0 0 0 INPUT VCC "rden" +// Retrieval info: USED_PORT: wren 0 0 0 0 INPUT NODEFVAL "wren" +// Retrieval info: CONNECT: @address_a 0 0 14 0 address 0 0 14 0 +// Retrieval info: CONNECT: @clock0 0 0 0 0 clock 0 0 0 0 +// Retrieval info: CONNECT: @data_a 0 0 8 0 data 0 0 8 0 +// Retrieval info: CONNECT: @rden_a 0 0 0 0 rden 0 0 0 0 +// Retrieval info: CONNECT: @wren_a 0 0 0 0 wren 0 0 0 0 +// Retrieval info: CONNECT: q 0 0 8 0 @q_a 0 0 8 0 +// Retrieval info: GEN_FILE: TYPE_NORMAL card.v TRUE +// Retrieval info: GEN_FILE: TYPE_NORMAL card.inc FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL card.cmp FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL card.bsf FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL card_inst.v FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL card_bb.v FALSE +// Retrieval info: LIB_FILE: altera_mf diff --git a/GCE - Vectrex_MiST/rtl/cpu09l_128a.vhd b/GCE - Vectrex_MiST/rtl/cpu09l_128a.vhd new file mode 100644 index 00000000..47b8eddd --- /dev/null +++ b/GCE - Vectrex_MiST/rtl/cpu09l_128a.vhd @@ -0,0 +1,5946 @@ +--===========================================================================-- +-- -- +-- 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) + rst : in std_logic; -- reset input (active high) + vma : out std_logic; -- valid memory address (active high) + lic_out : out std_logic; -- last instruction cycle (active high) + ifetch : out std_logic; -- instruction fetch cycle (active high) + opfetch : out std_logic; -- opcode fetch (active high) + ba : out std_logic; -- bus available (high on sync wait or DMA grant) + bs : out std_logic; -- bus status (high on interrupt or reset vector fetch or DMA grant) + addr : out std_logic_vector(15 downto 0); -- address bus output + rw : out std_logic; -- read not write output + data_out : out std_logic_vector(7 downto 0); -- data bus output + data_in : in std_logic_vector(7 downto 0); -- data bus input + irq : in std_logic; -- interrupt request input (active high) + firq : in std_logic; -- fast interrupt request input (active high) + nmi : in std_logic; -- non maskable interrupt request input (active high) + halt : in std_logic; -- halt input (active high) grants DMA + hold_in : in std_logic -- hold input (active high) extend bus cycle + ); +end cpu09; + +architecture rtl of cpu09 is + + constant EBIT : integer := 7; + constant FBIT : integer := 6; + constant HBIT : integer := 5; + constant IBIT : integer := 4; + constant NBIT : integer := 3; + constant ZBIT : integer := 2; + constant VBIT : integer := 1; + constant CBIT : integer := 0; + + -- + -- Interrupt vector modifiers + -- + constant RST_VEC : std_logic_vector(2 downto 0) := "111"; + constant NMI_VEC : std_logic_vector(2 downto 0) := "110"; + constant SWI_VEC : std_logic_vector(2 downto 0) := "101"; + constant IRQ_VEC : std_logic_vector(2 downto 0) := "100"; + constant FIRQ_VEC : std_logic_vector(2 downto 0) := "011"; + constant SWI2_VEC : std_logic_vector(2 downto 0) := "010"; + constant SWI3_VEC : std_logic_vector(2 downto 0) := "001"; + constant RESV_VEC : std_logic_vector(2 downto 0) := "000"; + + type state_type is (-- Start off in Reset + reset_state, + -- Fetch Interrupt Vectors (including reset) + vect_lo_state, vect_hi_state, vect_idle_state, + -- Fetch Instruction Cycle + fetch_state, + -- Decode Instruction Cycles + decode1_state, decode2_state, decode3_state, + -- Calculate Effective Address + imm16_state, + indexed_state, index8_state, index16_state, index16_2_state, + pcrel8_state, pcrel16_state, pcrel16_2_state, + indexaddr_state, indexaddr2_state, + postincr1_state, postincr2_state, + indirect_state, indirect2_state, indirect3_state, + extended_state, + -- single ops + single_op_read_state, + single_op_exec_state, + single_op_write_state, + -- Dual op states + dual_op_read8_state, dual_op_read16_state, dual_op_read16_2_state, + dual_op_write8_state, dual_op_write16_state, + -- + sync_state, halt_state, cwai_state, + -- + andcc_state, orcc_state, + tfr_state, + exg_state, exg1_state, exg2_state, + lea_state, + -- Multiplication + mul_state, mulea_state, muld_state, + mul0_state, mul1_state, mul2_state, mul3_state, + mul4_state, mul5_state, mul6_state, mul7_state, + -- Branches + lbranch_state, sbranch_state, + -- Jumps, Subroutine Calls and Returns + jsr_state, jmp_state, + push_return_hi_state, push_return_lo_state, + pull_return_hi_state, pull_return_lo_state, + -- Interrupt cycles + int_nmi_state, int_nmi1_state, + int_irq_state, int_irq1_state, + int_firq_state, int_firq1_state, + int_entire_state, int_fast_state, + int_pcl_state, int_pch_state, + int_upl_state, int_uph_state, + int_iyl_state, int_iyh_state, + int_ixl_state, int_ixh_state, + int_dp_state, + int_accb_state, int_acca_state, + int_cc_state, + int_cwai_state, + int_nmimask_state, int_firqmask_state, int_swimask_state, int_irqmask_state, + -- Return From Interrupt + rti_cc_state, rti_entire_state, + rti_acca_state, rti_accb_state, + rti_dp_state, + rti_ixl_state, rti_ixh_state, + rti_iyl_state, rti_iyh_state, + rti_upl_state, rti_uph_state, + rti_pcl_state, rti_pch_state, + -- Push Registers using SP + pshs_state, + pshs_pcl_state, pshs_pch_state, + pshs_upl_state, pshs_uph_state, + pshs_iyl_state, pshs_iyh_state, + pshs_ixl_state, pshs_ixh_state, + pshs_dp_state, + pshs_acca_state, pshs_accb_state, + pshs_cc_state, + -- Pull Registers using SP + puls_state, + puls_cc_state, + puls_acca_state, puls_accb_state, + puls_dp_state, + puls_ixl_state, puls_ixh_state, + puls_iyl_state, puls_iyh_state, + puls_upl_state, puls_uph_state, + puls_pcl_state, puls_pch_state, + -- Push Registers using UP + pshu_state, + pshu_pcl_state, pshu_pch_state, + pshu_spl_state, pshu_sph_state, + pshu_iyl_state, pshu_iyh_state, + pshu_ixl_state, pshu_ixh_state, + pshu_dp_state, + pshu_acca_state, pshu_accb_state, + pshu_cc_state, + -- Pull Registers using UP + pulu_state, + pulu_cc_state, + pulu_acca_state, pulu_accb_state, + pulu_dp_state, + pulu_ixl_state, pulu_ixh_state, + pulu_iyl_state, pulu_iyh_state, + pulu_spl_state, pulu_sph_state, + pulu_pcl_state, pulu_pch_state ); + + type st_type is (reset_st, push_st, idle_st ); + type iv_type is (latch_iv, swi3_iv, swi2_iv, firq_iv, irq_iv, swi_iv, nmi_iv, reset_iv); + type addr_type is (idle_ad, fetch_ad, read_ad, write_ad, pushu_ad, pullu_ad, pushs_ad, pulls_ad, int_hi_ad, int_lo_ad ); + type dout_type is (cc_dout, acca_dout, accb_dout, dp_dout, + ix_lo_dout, ix_hi_dout, iy_lo_dout, iy_hi_dout, + up_lo_dout, up_hi_dout, sp_lo_dout, sp_hi_dout, + pc_lo_dout, pc_hi_dout, md_lo_dout, md_hi_dout ); + type op_type is (reset_op, fetch_op, latch_op ); + type pre_type is (reset_pre, fetch_pre, latch_pre ); + type cc_type is (reset_cc, load_cc, pull_cc, latch_cc ); + type acca_type is (reset_acca, load_acca, load_hi_acca, pull_acca, latch_acca ); + type accb_type is (reset_accb, load_accb, pull_accb, latch_accb ); + type dp_type is (reset_dp, load_dp, pull_dp, latch_dp ); + type ix_type is (reset_ix, load_ix, pull_lo_ix, pull_hi_ix, latch_ix ); + type iy_type is (reset_iy, load_iy, pull_lo_iy, pull_hi_iy, latch_iy ); + type sp_type is (reset_sp, latch_sp, load_sp, pull_hi_sp, pull_lo_sp ); + type up_type is (reset_up, latch_up, load_up, pull_hi_up, pull_lo_up ); + type pc_type is (reset_pc, latch_pc, load_pc, pull_lo_pc, pull_hi_pc, incr_pc ); + type md_type is (reset_md, latch_md, load_md, fetch_first_md, fetch_next_md, shiftl_md ); + type ea_type is (reset_ea, latch_ea, load_ea, fetch_first_ea, fetch_next_ea ); + type left_type is (cc_left, acca_left, accb_left, dp_left, + ix_left, iy_left, up_left, sp_left, + accd_left, md_left, pc_left, ea_left ); + type right_type is (ea_right, zero_right, one_right, two_right, + acca_right, accb_right, accd_right, + md_right, md_sign5_right, md_sign8_right ); + type alu_type is (alu_add8, alu_sub8, alu_add16, alu_sub16, alu_adc, alu_sbc, + alu_and, alu_ora, alu_eor, + alu_tst, alu_inc, alu_dec, alu_clr, alu_neg, alu_com, + alu_lsr16, alu_lsl16, + alu_ror8, alu_rol8, alu_mul, + alu_asr8, alu_asl8, alu_lsr8, + alu_andcc, alu_orcc, alu_sex, alu_tfr, alu_abx, + alu_seif, alu_sei, alu_see, alu_cle, + alu_ld8, alu_st8, alu_ld16, alu_st16, alu_lea, alu_nop, alu_daa ); + + signal op_code: std_logic_vector(7 downto 0); + signal pre_code: std_logic_vector(7 downto 0); + signal acca: std_logic_vector(7 downto 0); + signal accb: std_logic_vector(7 downto 0); + signal cc: std_logic_vector(7 downto 0); + signal cc_out: std_logic_vector(7 downto 0); + signal dp: std_logic_vector(7 downto 0); + signal xreg: std_logic_vector(15 downto 0); + signal yreg: std_logic_vector(15 downto 0); + signal sp: std_logic_vector(15 downto 0); + signal up: std_logic_vector(15 downto 0); + signal ea: std_logic_vector(15 downto 0); + signal pc: std_logic_vector(15 downto 0); + signal md: std_logic_vector(15 downto 0); + signal left: std_logic_vector(15 downto 0); + signal right: std_logic_vector(15 downto 0); + signal out_alu: std_logic_vector(15 downto 0); + signal iv: std_logic_vector(2 downto 0); + signal nmi_req: std_logic; + signal nmi_ack: std_logic; + signal nmi_enable: std_logic; + signal fic: std_logic; -- first instruction cycle + signal lic: std_logic; -- last instruction cycle + + signal state: state_type; + signal next_state: state_type; + signal return_state: state_type; + signal saved_state: state_type; + signal st_ctrl: st_type; + signal iv_ctrl: iv_type; + signal pc_ctrl: pc_type; + signal ea_ctrl: ea_type; + signal op_ctrl: op_type; + signal pre_ctrl: pre_type; + signal md_ctrl: md_type; + signal acca_ctrl: acca_type; + signal accb_ctrl: accb_type; + signal ix_ctrl: ix_type; + signal iy_ctrl: iy_type; + signal cc_ctrl: cc_type; + signal dp_ctrl: dp_type; + signal sp_ctrl: sp_type; + signal up_ctrl: up_type; + signal left_ctrl: left_type; + signal right_ctrl: right_type; + signal alu_ctrl: alu_type; + signal addr_ctrl: addr_type; + signal dout_ctrl: dout_type; + + + 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 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 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 hold = '0' then + case st_ctrl is + when reset_st => + saved_state <= fetch_state; + when push_st => + saved_state <= return_state; + when others => + null; + end case; + end if; + end if; +end process; + +---------------------------------- +-- +-- Interrupt Vector control +-- +---------------------------------- +-- +int_vec_proc: process( clk, iv_ctrl ) +begin + if clk'event and clk = '0' then + if hold = '0' then + case iv_ctrl is + when reset_iv => + iv <= RST_VEC; + when nmi_iv => + iv <= NMI_VEC; + when swi_iv => + iv <= SWI_VEC; + when irq_iv => + iv <= IRQ_VEC; + when firq_iv => + iv <= FIRQ_VEC; + when swi2_iv => + iv <= SWI2_VEC; + when swi3_iv => + iv <= SWI3_VEC; + when others => + null; + end case; + end if; -- hold + end if; -- clk +end process; + +---------------------------------- +-- +-- Program Counter Control +-- +---------------------------------- + +--pc_reg: process( clk, pc_ctrl, hold, pc, out_alu, data_in ) +pc_reg: process( clk ) +begin + if clk'event and clk = '0' then + if hold = '0' then + case pc_ctrl is + when reset_pc => + pc <= (others=>'0'); + when load_pc => + pc <= out_alu(15 downto 0); + when pull_lo_pc => + pc(7 downto 0) <= data_in; + when pull_hi_pc => + pc(15 downto 8) <= data_in; + when incr_pc => + pc <= pc + 1; + when others => + null; + end case; + end if; + end if; +end process; + +---------------------------------- +-- +-- Effective Address Control +-- +---------------------------------- + +--ea_reg: process( clk, ea_ctrl, hold, ea, out_alu, data_in, dp ) +ea_reg: process( clk ) +begin + + if clk'event and clk = '0' then + if hold= '0' then + case ea_ctrl is + when reset_ea => + ea <= (others=>'0'); + when fetch_first_ea => + ea(7 downto 0) <= data_in; + ea(15 downto 8) <= dp; + when fetch_next_ea => + ea(15 downto 8) <= ea(7 downto 0); + ea(7 downto 0) <= data_in; + when load_ea => + ea <= out_alu(15 downto 0); + when others => + null; + end case; + end if; + end if; +end process; + +-------------------------------- +-- +-- Accumulator A +-- +-------------------------------- +--acca_reg : process( clk, acca_ctrl, hold, out_alu, acca, data_in ) +acca_reg : process( clk ) +begin + if clk'event and clk = '0' then + if hold = '0' then + case acca_ctrl is + when reset_acca => + acca <= (others=>'0'); + when load_acca => + acca <= out_alu(7 downto 0); + when load_hi_acca => + acca <= out_alu(15 downto 8); + when pull_acca => + acca <= data_in; + when others => + null; + end case; + end if; + end if; +end process; + +-------------------------------- +-- +-- Accumulator B +-- +-------------------------------- +--accb_reg : process( clk, accb_ctrl, hold, out_alu, accb, data_in ) +accb_reg : process( clk ) +begin + if clk'event and clk = '0' then + if hold = '0' then + case accb_ctrl is + when reset_accb => + accb <= (others=>'0'); + when load_accb => + accb <= out_alu(7 downto 0); + when pull_accb => + accb <= data_in; + when others => + null; + end case; + end if; + end if; +end process; + +-------------------------------- +-- +-- X Index register +-- +-------------------------------- +--ix_reg : process( clk, ix_ctrl, hold, out_alu, xreg, data_in ) +ix_reg : process( clk ) +begin + if clk'event and clk = '0' then + if hold = '0' then + case ix_ctrl is + when reset_ix => + xreg <= (others=>'0'); + when load_ix => + xreg <= out_alu(15 downto 0); + when pull_hi_ix => + xreg(15 downto 8) <= data_in; + when pull_lo_ix => + xreg(7 downto 0) <= data_in; + when others => + null; + end case; + end if; + end if; +end process; + +-------------------------------- +-- +-- Y Index register +-- +-------------------------------- +--iy_reg : process( clk, iy_ctrl, hold, out_alu, yreg, data_in ) +iy_reg : process( clk ) +begin + if clk'event and clk = '0' then + if hold = '0' then + case iy_ctrl is + when reset_iy => + yreg <= (others=>'0'); + when load_iy => + yreg <= out_alu(15 downto 0); + when pull_hi_iy => + yreg(15 downto 8) <= data_in; + when pull_lo_iy => + yreg(7 downto 0) <= data_in; + when others => + null; + end case; + end if; + end if; +end process; + +-------------------------------- +-- +-- S stack pointer +-- +-------------------------------- +--sp_reg : process( clk, sp_ctrl, hold, sp, out_alu, data_in, nmi_enable ) +sp_reg : process( clk ) +begin + if clk'event and clk = '0' then + if hold = '0' then + case sp_ctrl is + when reset_sp => + sp <= (others=>'0'); + nmi_enable <= '0'; + when load_sp => + sp <= out_alu(15 downto 0); + nmi_enable <= '1'; + when pull_hi_sp => + sp(15 downto 8) <= data_in; + when pull_lo_sp => + sp(7 downto 0) <= data_in; + nmi_enable <= '1'; + when others => + null; + end case; + end if; + end if; +end process; + +-------------------------------- +-- +-- U stack pointer +-- +-------------------------------- +--up_reg : process( clk, up_ctrl, hold, up, out_alu, data_in ) +up_reg : process( clk ) +begin + if clk'event and clk = '0' then + if hold = '0' then + case up_ctrl is + when reset_up => + up <= (others=>'0'); + when load_up => + up <= out_alu(15 downto 0); + when pull_hi_up => + up(15 downto 8) <= data_in; + when pull_lo_up => + up(7 downto 0) <= data_in; + when others => + null; + end case; + end if; + end if; +end process; + +-------------------------------- +-- +-- Memory Data +-- +-------------------------------- +--md_reg : process( clk, md_ctrl, hold, out_alu, data_in, md ) +md_reg : process( clk ) +begin + if clk'event and clk = '0' then + if hold = '0' then + case md_ctrl is + when reset_md => + md <= (others=>'0'); + when load_md => + md <= out_alu(15 downto 0); + when fetch_first_md => -- sign extend md for branches + md(15 downto 8) <= data_in(7) & data_in(7) & data_in(7) & data_in(7) & + data_in(7) & data_in(7) & data_in(7) & data_in(7) ; + md(7 downto 0) <= data_in; + when fetch_next_md => + md(15 downto 8) <= md(7 downto 0); + md(7 downto 0) <= data_in; + when shiftl_md => + md(15 downto 1) <= md(14 downto 0); + md(0) <= '0'; + when others => + null; + end case; + end if; + end if; +end process; + + +---------------------------------- +-- +-- Condition Codes +-- +---------------------------------- + +--cc_reg: process( clk, cc_ctrl, hold, cc_out, cc, data_in ) +cc_reg: process( clk ) +begin + if clk'event and clk = '0' then + if hold = '0' then + case cc_ctrl is + when reset_cc => + cc <= "11010000"; -- set EBIT, FBIT & IBIT + when load_cc => + cc <= cc_out; + when pull_cc => + cc <= data_in; + when others => + null; + end case; + end if; + end if; +end process; + +---------------------------------- +-- +-- Direct Page register +-- +---------------------------------- + +--dp_reg: process( clk, dp_ctrl, hold, out_alu, dp, data_in ) +dp_reg: process( clk ) +begin + if clk'event and clk = '0' then + if hold = '0' then + case dp_ctrl is + when reset_dp => + dp <= (others=>'0'); + when load_dp => + dp <= out_alu(7 downto 0); + when pull_dp => + dp <= data_in; + when others => + null; + end case; + end if; + end if; +end process; + + +---------------------------------- +-- +-- op code register +-- +---------------------------------- + +--op_reg: process( clk, op_ctrl, hold, op_code, data_in ) +op_reg: process( clk ) +begin + if clk'event and clk = '0' then + if hold = '0' then + case op_ctrl is + when reset_op => + op_code <= "00010010"; + when fetch_op => + op_code <= data_in; + when others => + null; + end case; + end if; + end if; +end process; + + +---------------------------------- +-- +-- pre byte op code register +-- +---------------------------------- + +--pre_reg: process( clk, pre_ctrl, hold, pre_code, data_in ) +pre_reg: process( clk ) +begin + if clk'event and clk = '0' then + if hold = '0' then + case pre_ctrl is + when reset_pre => + pre_code <= (others=>'0'); + when fetch_pre => + pre_code <= data_in; + when others => + null; + end case; + end if; + end if; +end process; + +-------------------------------- +-- +-- state machine +-- +-------------------------------- + +--change_state: process( clk, rst, state, hold, next_state ) +change_state: process( clk ) +begin + if clk'event and clk = '0' then + + if rst = '1' then + fic <= '0'; + nmi_ack <= '0'; + state <= reset_state; + elsif hold = '0' then + + fic <= lic; + -- + -- nmi request is not cleared until nmi input goes low + -- + if (nmi_req = '0') and (nmi_ack='1') then + nmi_ack <= '0'; + end if; + + if (nmi_req = '1') and (nmi_ack = '0') and (state = int_nmimask_state) then + nmi_ack <= '1'; + end if; + + if lic = '1' then + if halt = '1' then + state <= halt_state; + + -- service non maskable interrupts + elsif (nmi_req = '1') and (nmi_ack = '0') then + state <= int_nmi_state; + -- + -- FIRQ & IRQ are level sensitive + -- + elsif (firq = '1') and (cc(FBIT) = '0') then + state <= int_firq_state; + + elsif (irq = '1') and (cc(IBIT) = '0') then + state <= int_irq_state; + -- + -- Version 1.27 2015-05-30 + -- Exit sync_state on masked interrupt. + -- + -- Version 1.28 2015-05-30 + -- Move this code to the state sequencer + -- near line 5566. + -- + -- elsif (state = sync_state) and ((firq = '1') or (irq = '1'))then + -- state <= fetch_state; + -- + else + state <= next_state; + end if; -- halt, nmi, firq, irq + else + state <= next_state; + end if; -- lic + end if; -- reset/hold + end if; -- clk +end process; + +------------------------------------ +-- +-- Detect Edge of NMI interrupt +-- +------------------------------------ + +--nmi_handler : process( clk, rst, nmi, nmi_ack, nmi_req, nmi_enable ) +nmi_handler : process( rst, clk ) +begin + if rst='1' then + nmi_req <= '0'; + elsif clk'event and clk='0' then + if (nmi='1') and (nmi_ack='0') and (nmi_enable='1') then + nmi_req <= '1'; + else + if (nmi='0') and (nmi_ack='1') then + nmi_req <= '0'; + end if; + end if; + end if; +end process; + + +---------------------------------- +-- +-- Address output multiplexer +-- +---------------------------------- + +addr_mux: process( addr_ctrl, pc, ea, up, sp, iv ) +begin + ifetch <= '0'; + vma <= '1'; + case addr_ctrl is + when fetch_ad => + addr <= pc; + rw <= '1'; + ifetch <= '1'; + when read_ad => + addr <= ea; + rw <= '1'; + when write_ad => + addr <= ea; + rw <= '0'; + when pushs_ad => + addr <= sp; + rw <= '0'; + when pulls_ad => + addr <= sp; + rw <= '1'; + when pushu_ad => + addr <= up; + rw <= '0'; + when pullu_ad => + addr <= up; + rw <= '1'; + when int_hi_ad => + addr <= "111111111111" & iv & "0"; + rw <= '1'; + when int_lo_ad => + addr <= "111111111111" & iv & "1"; + rw <= '1'; + when others => + addr <= "1111111111111111"; + rw <= '1'; + vma <= '0'; + end case; +end process; + +-------------------------------- +-- +-- Data Bus output +-- +-------------------------------- +dout_mux : process( dout_ctrl, md, acca, accb, dp, xreg, yreg, sp, up, pc, cc ) +begin + case dout_ctrl is + when cc_dout => -- condition code register + data_out <= cc; + when acca_dout => -- accumulator a + data_out <= acca; + when accb_dout => -- accumulator b + data_out <= accb; + when dp_dout => -- direct page register + data_out <= dp; + when ix_lo_dout => -- X index reg + data_out <= xreg(7 downto 0); + when ix_hi_dout => -- X index reg + data_out <= xreg(15 downto 8); + when iy_lo_dout => -- Y index reg + data_out <= yreg(7 downto 0); + when iy_hi_dout => -- Y index reg + data_out <= yreg(15 downto 8); + when up_lo_dout => -- U stack pointer + data_out <= up(7 downto 0); + when up_hi_dout => -- U stack pointer + data_out <= up(15 downto 8); + when sp_lo_dout => -- S stack pointer + data_out <= sp(7 downto 0); + when sp_hi_dout => -- S stack pointer + data_out <= sp(15 downto 8); + when md_lo_dout => -- alu output + data_out <= md(7 downto 0); + when md_hi_dout => -- alu output + data_out <= md(15 downto 8); + when pc_lo_dout => -- low order pc + data_out <= pc(7 downto 0); + when pc_hi_dout => -- high order pc + data_out <= pc(15 downto 8); + end case; +end process; + +---------------------------------- +-- +-- Left Mux +-- +---------------------------------- + +left_mux: process( left_ctrl, acca, accb, cc, dp, xreg, yreg, up, sp, pc, ea, md ) +begin + case left_ctrl is + when cc_left => + left(15 downto 8) <= "00000000"; + left(7 downto 0) <= cc; + when acca_left => + left(15 downto 8) <= "00000000"; + left(7 downto 0) <= acca; + when accb_left => + left(15 downto 8) <= "00000000"; + left(7 downto 0) <= accb; + when dp_left => + left(15 downto 8) <= "00000000"; + left(7 downto 0) <= dp; + when accd_left => + left(15 downto 8) <= acca; + left(7 downto 0) <= accb; + when md_left => + left <= md; + when ix_left => + left <= xreg; + when iy_left => + left <= yreg; + when sp_left => + left <= sp; + when up_left => + left <= up; + when pc_left => + left <= pc; + when others => +-- when ea_left => + left <= ea; + end case; +end process; + +---------------------------------- +-- +-- Right Mux +-- +---------------------------------- + +right_mux: process( right_ctrl, md, acca, accb, ea ) +begin + case right_ctrl is + when ea_right => + right <= ea; + when zero_right => + right <= "0000000000000000"; + when one_right => + right <= "0000000000000001"; + when two_right => + right <= "0000000000000010"; + when acca_right => + if acca(7) = '0' then + right <= "00000000" & acca(7 downto 0); + else + right <= "11111111" & acca(7 downto 0); + end if; + when accb_right => + if accb(7) = '0' then + right <= "00000000" & accb(7 downto 0); + else + right <= "11111111" & accb(7 downto 0); + end if; + when accd_right => + right <= acca & accb; + when md_sign5_right => + if md(4) = '0' then + right <= "00000000000" & md(4 downto 0); + else + right <= "11111111111" & md(4 downto 0); + end if; + when md_sign8_right => + if md(7) = '0' then + right <= "00000000" & md(7 downto 0); + else + right <= "11111111" & md(7 downto 0); + end if; + when others => +-- when md_right => + right <= md; + end case; +end process; + +---------------------------------- +-- +-- Arithmetic Logic Unit +-- +---------------------------------- + +alu: process( alu_ctrl, cc, left, right, out_alu, cc_out ) +variable valid_lo, valid_hi : boolean; +variable carry_in : std_logic; +variable daa_reg : std_logic_vector(7 downto 0); +begin + + case alu_ctrl is + when alu_adc | alu_sbc | + alu_rol8 | alu_ror8 => + carry_in := cc(CBIT); + when alu_asr8 => + carry_in := left(7); + when others => + carry_in := '0'; + end case; + + valid_lo := left(3 downto 0) <= 9; + valid_hi := left(7 downto 4) <= 9; + + -- + -- CBIT HBIT VHI VLO DAA + -- 0 0 0 0 66 (!VHI : hi_nybble>8) + -- 0 0 0 1 60 + -- 0 0 1 1 00 + -- 0 0 1 0 06 ( VHI : hi_nybble<=8) + -- + -- 0 1 1 0 06 + -- 0 1 1 1 06 + -- 0 1 0 1 66 + -- 0 1 0 0 66 + -- + -- 1 1 0 0 66 + -- 1 1 0 1 66 + -- 1 1 1 1 66 + -- 1 1 1 0 66 + -- + -- 1 0 1 0 66 + -- 1 0 1 1 60 + -- 1 0 0 1 60 + -- 1 0 0 0 66 + -- + -- 66 = (!VHI & !VLO) + (CBIT & HBIT) + (HBIT & !VHI) + (CBIT & !VLO) + -- = (CBIT & (HBIT + !VLO)) + (!VHI & (HBIT + !VLO)) + -- = (!VLO & (CBIT + !VHI)) + (HBIT & (CBIT + !VHI)) + -- 60 = (CBIT & !HBIT & VLO) + (!HBIT & !VHI & VLO) + -- = (!HBIT & VLO & (CBIT + !VHI)) + -- 06 = (!CBIT & VHI & (!VLO + VHI) + -- 00 = (!CBIT & !HBIT & VHI & VLO) + -- + if (cc(CBIT) = '0') then + -- CBIT=0 + if( cc(HBIT) = '0' ) then + -- HBIT=0 + if valid_lo then + -- lo <= 9 (no overflow in low nybble) + if valid_hi then + -- hi <= 9 (no overflow in either low or high nybble) + daa_reg := "00000000"; + else + -- hi > 9 (overflow in high nybble only) + daa_reg := "01100000"; + end if; + else + -- lo > 9 (overflow in low nybble) + -- + -- since there is already an overflow in the low nybble + -- you need to make room in the high nybble for the low nybble carry + -- so compare the high nybble with 8 rather than 9 + -- if the high nybble is 9 there will be an overflow on the high nybble + -- after the decimal adjust which means it will roll over to an invalid BCD digit + -- + if( left(7 downto 4) <= 8 ) then + -- hi <= 8 (overflow in low nybble only) + daa_reg := "00000110"; + else + -- hi > 8 (overflow in low and high nybble) + daa_reg := "01100110"; + end if; + end if; + else + -- HBIT=1 (overflow in low nybble) + if valid_hi then + -- hi <= 9 (overflow in low nybble only) + daa_reg := "00000110"; + else + -- hi > 9 (overflow in low and high nybble) + daa_reg := "01100110"; + end if; + end if; + else + -- CBIT=1 (carry => overflow in high nybble) + if ( cc(HBIT) = '0' )then + -- HBIT=0 (half carry clear => may or may not be an overflow in the low nybble) + if valid_lo then + -- lo <=9 (overflow in high nybble only) + daa_reg := "01100000"; + else + -- lo >9 (overflow in low and high nybble) + daa_reg := "01100110"; + end if; + else + -- HBIT=1 (overflow in low and high nybble) + daa_reg := "01100110"; + end if; + end if; + + case alu_ctrl is + when alu_add8 | alu_inc | + alu_add16 | alu_adc | alu_mul => + out_alu <= left + right + ("000000000000000" & carry_in); + when alu_sub8 | alu_dec | + alu_sub16 | alu_sbc => + out_alu <= left - right - ("000000000000000" & carry_in); + when alu_abx => + out_alu <= left + ("00000000" & right(7 downto 0)) ; + when alu_and => + out_alu <= left and right; -- and/bit + when alu_ora => + out_alu <= left or right; -- or + when alu_eor => + out_alu <= left xor right; -- eor/xor + when alu_lsl16 | alu_asl8 | alu_rol8 => + out_alu <= left(14 downto 0) & carry_in; -- rol8/asl8/lsl16 + when alu_lsr16 => + out_alu <= carry_in & left(15 downto 1); -- lsr16 + when alu_lsr8 | alu_asr8 | alu_ror8 => + out_alu <= "00000000" & carry_in & left(7 downto 1); -- ror8/asr8/lsr8 + when alu_neg => + out_alu <= right - left; -- neg (right=0) + when alu_com => + out_alu <= not left; + when alu_clr | alu_ld8 | alu_ld16 | alu_lea => + out_alu <= right; -- clr, ld + when alu_st8 | alu_st16 | alu_andcc | alu_orcc | alu_tfr => + out_alu <= left; + when alu_daa => + out_alu <= left + ("00000000" & daa_reg); + when alu_sex => + if left(7) = '0' then + out_alu <= "00000000" & left(7 downto 0); + else + out_alu <= "11111111" & left(7 downto 0); + end if; + when others => + out_alu <= left; -- nop + end case; + + -- + -- carry bit + -- + case alu_ctrl is + when alu_add8 | alu_adc => + cc_out(CBIT) <= (left(7) and right(7)) or + (left(7) and not out_alu(7)) or + (right(7) and not out_alu(7)); + when alu_sub8 | alu_sbc => + cc_out(CBIT) <= ((not left(7)) and right(7)) or + ((not left(7)) and out_alu(7)) or + (right(7) and out_alu(7)); + when alu_add16 => + cc_out(CBIT) <= (left(15) and right(15)) or + (left(15) and not out_alu(15)) or + (right(15) and not out_alu(15)); + when alu_sub16 => + cc_out(CBIT) <= ((not left(15)) and right(15)) or + ((not left(15)) and out_alu(15)) or + (right(15) and out_alu(15)); + when alu_ror8 | alu_lsr16 | alu_lsr8 | alu_asr8 => + cc_out(CBIT) <= left(0); + when alu_rol8 | alu_asl8 => + cc_out(CBIT) <= left(7); + when alu_lsl16 => + cc_out(CBIT) <= left(15); + when alu_com => + cc_out(CBIT) <= '1'; + when alu_neg | alu_clr => + cc_out(CBIT) <= out_alu(7) or out_alu(6) or out_alu(5) or out_alu(4) or + out_alu(3) or out_alu(2) or out_alu(1) or out_alu(0); + when alu_mul => + cc_out(CBIT) <= out_alu(7); + when alu_daa => + if ( daa_reg(7 downto 4) = "0110" ) then + cc_out(CBIT) <= '1'; + else + cc_out(CBIT) <= '0'; + end if; + when alu_andcc => + cc_out(CBIT) <= left(CBIT) and cc(CBIT); + when alu_orcc => + cc_out(CBIT) <= left(CBIT) or cc(CBIT); + when alu_tfr => + cc_out(CBIT) <= left(CBIT); + when others => + cc_out(CBIT) <= cc(CBIT); + end case; + -- + -- Zero flag + -- + case alu_ctrl is + when alu_add8 | alu_sub8 | + alu_adc | alu_sbc | + alu_and | alu_ora | alu_eor | + alu_inc | alu_dec | + alu_neg | alu_com | alu_clr | + alu_rol8 | alu_ror8 | alu_asr8 | alu_asl8 | alu_lsr8 | + alu_ld8 | alu_st8 | alu_sex | alu_daa => + cc_out(ZBIT) <= not( out_alu(7) or out_alu(6) or out_alu(5) or out_alu(4) or + out_alu(3) or out_alu(2) or out_alu(1) or out_alu(0) ); + when alu_add16 | alu_sub16 | alu_mul | + alu_lsl16 | alu_lsr16 | + alu_ld16 | alu_st16 | alu_lea => + cc_out(ZBIT) <= not( out_alu(15) or out_alu(14) or out_alu(13) or out_alu(12) or + out_alu(11) or out_alu(10) or out_alu(9) or out_alu(8) or + out_alu(7) or out_alu(6) or out_alu(5) or out_alu(4) or + out_alu(3) or out_alu(2) or out_alu(1) or out_alu(0) ); + when alu_andcc => + cc_out(ZBIT) <= left(ZBIT) and cc(ZBIT); + when alu_orcc => + cc_out(ZBIT) <= left(ZBIT) or cc(ZBIT); + when alu_tfr => + cc_out(ZBIT) <= left(ZBIT); + when others => + cc_out(ZBIT) <= cc(ZBIT); + end case; + + -- + -- negative flag + -- + case alu_ctrl is + when alu_add8 | alu_sub8 | + alu_adc | alu_sbc | + alu_and | alu_ora | alu_eor | + alu_rol8 | alu_ror8 | alu_asr8 | alu_asl8 | alu_lsr8 | + alu_inc | alu_dec | alu_neg | alu_com | alu_clr | + alu_ld8 | alu_st8 | alu_sex | alu_daa => + cc_out(NBIT) <= out_alu(7); + when alu_add16 | alu_sub16 | + alu_lsl16 | alu_lsr16 | + alu_ld16 | alu_st16 => + cc_out(NBIT) <= out_alu(15); + when alu_andcc => + cc_out(NBIT) <= left(NBIT) and cc(NBIT); + when alu_orcc => + cc_out(NBIT) <= left(NBIT) or cc(NBIT); + when alu_tfr => + cc_out(NBIT) <= left(NBIT); + when others => + cc_out(NBIT) <= cc(NBIT); + end case; + + -- + -- Interrupt mask flag + -- + case alu_ctrl is + when alu_andcc => + cc_out(IBIT) <= left(IBIT) and cc(IBIT); + when alu_orcc => + cc_out(IBIT) <= left(IBIT) or cc(IBIT); + when alu_tfr => + cc_out(IBIT) <= left(IBIT); + when alu_seif | alu_sei => + cc_out(IBIT) <= '1'; + when others => + cc_out(IBIT) <= cc(IBIT); -- interrupt mask + end case; + + -- + -- Half Carry flag + -- + case alu_ctrl is + when alu_add8 | alu_adc => + cc_out(HBIT) <= (left(3) and right(3)) or + (right(3) and not out_alu(3)) or + (left(3) and not out_alu(3)); + when alu_andcc => + cc_out(HBIT) <= left(HBIT) and cc(HBIT); + when alu_orcc => + cc_out(HBIT) <= left(HBIT) or cc(HBIT); + when alu_tfr => + cc_out(HBIT) <= left(HBIT); + when others => + cc_out(HBIT) <= cc(HBIT); + end case; + + -- + -- Overflow flag + -- + case alu_ctrl is + when alu_add8 | alu_adc => + cc_out(VBIT) <= (left(7) and right(7) and (not out_alu(7))) or + ((not left(7)) and (not right(7)) and out_alu(7)); + when alu_sub8 | alu_sbc => + cc_out(VBIT) <= (left(7) and (not right(7)) and (not out_alu(7))) or + ((not left(7)) and right(7) and out_alu(7)); + when alu_add16 => + cc_out(VBIT) <= (left(15) and right(15) and (not out_alu(15))) or + ((not left(15)) and (not right(15)) and out_alu(15)); + when alu_sub16 => + cc_out(VBIT) <= (left(15) and (not right(15)) and (not out_alu(15))) or + ((not left(15)) and right(15) and out_alu(15)); + when alu_inc => + cc_out(VBIT) <= ((not left(7)) and left(6) and left(5) and left(4) and + left(3) and left(2) and left(1) and left(0)); + when alu_dec | alu_neg => + cc_out(VBIT) <= (left(7) and (not left(6)) and (not left(5)) and (not left(4)) and + (not left(3)) and (not left(2)) and (not left(1)) and (not left(0))); +-- 6809 Programming reference manual says +-- V not affected by ASR, LSR and ROR +-- This is different to the 6800 +-- John Kent 6th June 2006 +-- when alu_asr8 => +-- cc_out(VBIT) <= left(0) xor left(7); +-- when alu_lsr8 | alu_lsr16 => +-- cc_out(VBIT) <= left(0); +-- when alu_ror8 => +-- cc_out(VBIT) <= left(0) xor cc(CBIT); + when alu_lsl16 => + cc_out(VBIT) <= left(15) xor left(14); + when alu_rol8 | alu_asl8 => + cc_out(VBIT) <= left(7) xor left(6); +-- +-- 11th July 2006 - John Kent +-- What DAA does with V is anyones guess +-- It is undefined in the 6809 programming manual +-- + when alu_daa => + cc_out(VBIT) <= left(7) xor out_alu(7) xor cc(CBIT); +-- CLR resets V Bit +-- John Kent 6th June 2006 + when alu_and | alu_ora | alu_eor | alu_com | alu_clr | + alu_st8 | alu_st16 | alu_ld8 | alu_ld16 | alu_sex => + cc_out(VBIT) <= '0'; + when alu_andcc => + cc_out(VBIT) <= left(VBIT) and cc(VBIT); + when alu_orcc => + cc_out(VBIT) <= left(VBIT) or cc(VBIT); + when alu_tfr => + cc_out(VBIT) <= left(VBIT); + when others => + cc_out(VBIT) <= cc(VBIT); + end case; + + case alu_ctrl is + when alu_andcc => + cc_out(FBIT) <= left(FBIT) and cc(FBIT); + when alu_orcc => + cc_out(FBIT) <= left(FBIT) or cc(FBIT); + when alu_tfr => + cc_out(FBIT) <= left(FBIT); + when alu_seif => + cc_out(FBIT) <= '1'; + when others => + cc_out(FBIT) <= cc(FBIT); + end case; + + case alu_ctrl is + when alu_andcc => + cc_out(EBIT) <= left(EBIT) and cc(EBIT); + when alu_orcc => + cc_out(EBIT) <= left(EBIT) or cc(EBIT); + when alu_tfr => + cc_out(EBIT) <= left(EBIT); + when alu_see => + cc_out(EBIT) <= '1'; + when alu_cle => + cc_out(EBIT) <= '0'; + when others => + cc_out(EBIT) <= cc(EBIT); + end case; +end process; + +------------------------------------ +-- +-- state sequencer +-- +------------------------------------ +process( state, saved_state, + op_code, pre_code, + cc, ea, md, iv, fic, halt, + nmi_req, firq, irq, lic ) +variable cond_true : boolean; -- variable used to evaluate coditional branches +begin + cond_true := (1=1); + ba <= '0'; + bs <= '0'; + lic <= '0'; + opfetch <= '0'; + iv_ctrl <= latch_iv; + -- Registers preserved + cc_ctrl <= latch_cc; + acca_ctrl <= latch_acca; + accb_ctrl <= latch_accb; + dp_ctrl <= latch_dp; + ix_ctrl <= latch_ix; + iy_ctrl <= latch_iy; + up_ctrl <= latch_up; + sp_ctrl <= latch_sp; + pc_ctrl <= latch_pc; + md_ctrl <= latch_md; + ea_ctrl <= latch_ea; + op_ctrl <= latch_op; + pre_ctrl <= latch_pre; + -- ALU Idle + left_ctrl <= pc_left; + right_ctrl <= zero_right; + alu_ctrl <= alu_nop; + -- Bus idle + addr_ctrl <= idle_ad; + dout_ctrl <= cc_dout; + -- Next State Fetch + st_ctrl <= idle_st; + return_state <= fetch_state; + next_state <= fetch_state; + + case state is + when reset_state => -- released from reset + -- reset the registers + iv_ctrl <= reset_iv; + op_ctrl <= reset_op; + pre_ctrl <= reset_pre; + cc_ctrl <= reset_cc; + acca_ctrl <= reset_acca; + accb_ctrl <= reset_accb; + dp_ctrl <= reset_dp; + ix_ctrl <= reset_ix; + iy_ctrl <= reset_iy; + up_ctrl <= reset_up; + sp_ctrl <= reset_sp; + pc_ctrl <= reset_pc; + ea_ctrl <= reset_ea; + md_ctrl <= reset_md; + st_ctrl <= reset_st; + next_state <= vect_hi_state; + + -- + -- Jump via interrupt vector + -- iv holds interrupt type + -- fetch PC hi from vector location + -- + when vect_hi_state => + -- fetch pc low interrupt vector + pc_ctrl <= pull_hi_pc; + addr_ctrl <= int_hi_ad; + bs <= '1'; + next_state <= vect_lo_state; + + -- + -- jump via interrupt vector + -- iv holds vector type + -- fetch PC lo from vector location + -- + when vect_lo_state => + -- fetch the vector low byte + pc_ctrl <= pull_lo_pc; + addr_ctrl <= int_lo_ad; + bs <= '1'; + next_state <= fetch_state; + + when vect_idle_state => + -- + -- Last Instruction Cycle for SWI, SWI2 & SWI3 + -- + if op_code = "00111111" then + lic <= '1'; + end if; + next_state <= fetch_state; + + -- + -- Here to fetch an instruction + -- PC points to opcode + -- + when fetch_state => + -- fetch the op code + opfetch <= '1'; + op_ctrl <= fetch_op; + pre_ctrl <= fetch_pre; + ea_ctrl <= reset_ea; + -- Fetch op code + addr_ctrl <= fetch_ad; + -- Advance the PC to fetch next instruction byte + pc_ctrl <= incr_pc; + next_state <= decode1_state; + + -- + -- Here to decode instruction + -- and fetch next byte of intruction + -- whether it be necessary or not + -- + when decode1_state => + -- fetch first byte of address or immediate data + ea_ctrl <= fetch_first_ea; + md_ctrl <= fetch_first_md; + addr_ctrl <= fetch_ad; + case op_code(7 downto 4) is + -- + -- direct single op (2 bytes) + -- 6809 => 6 cycles + -- cpu09 => 5 cycles + -- 1 op=(pc) / pc=pc+1 + -- 2 ea_hi=dp / ea_lo=(pc) / pc=pc+1 + -- 3 md_lo=(ea) / pc=pc + -- 4 alu_left=md / md=alu_out / pc=pc + -- 5 (ea)=md_lo / pc=pc + -- + -- Exception is JMP + -- 6809 => 3 cycles + -- cpu09 => 3 cycles + -- 1 op=(pc) / pc=pc+1 + -- 2 ea_hi=dp / ea_lo=(pc) / pc=pc+1 + -- 3 pc=ea + -- + when "0000" => + -- advance the PC + pc_ctrl <= incr_pc; + + case op_code(3 downto 0) is + when "1110" => -- jmp + next_state <= jmp_state; + + when "1111" => -- clr + next_state <= single_op_exec_state; + + when others => + next_state <= single_op_read_state; + + end case; + + -- acca / accb inherent instructions + when "0001" => + case op_code(3 downto 0) is + -- + -- Page2 pre byte + -- pre=(pc) / pc=pc+1 + -- op=(pc) / pc=pc+1 + -- + when "0000" => -- page2 + opfetch <= '1'; + op_ctrl <= fetch_op; + -- advance pc + pc_ctrl <= incr_pc; + next_state <= decode2_state; + + -- + -- Page3 pre byte + -- pre=(pc) / pc=pc+1 + -- op=(pc) / pc=pc+1 + -- + when "0001" => -- page3 + opfetch <= '1'; + op_ctrl <= fetch_op; + -- advance pc + pc_ctrl <= incr_pc; + next_state <= decode3_state; + + -- + -- nop - No operation ( 1 byte ) + -- 6809 => 2 cycles + -- cpu09 => 2 cycles + -- 1 op=(pc) / pc=pc+1 + -- 2 decode + -- + when "0010" => -- nop + lic <= '1'; + next_state <= fetch_state; + + -- + -- sync - halt execution until an interrupt is received + -- interrupt may be NMI, IRQ or FIRQ + -- program execution continues if the + -- interrupt is asserted for 3 clock cycles + -- note that registers are not pushed onto the stack + -- CPU09 => Interrupts need only be asserted for one clock cycle + -- + when "0011" => -- sync + next_state <= sync_state; + + -- + -- lbra -- long branch (3 bytes) + -- 6809 => 5 cycles + -- cpu09 => 4 cycles + -- 1 op=(pc) / pc=pc+1 + -- 2 md_hi=sign(pc) / md_lo=(pc) / pc=pc+1 + -- 3 md_hi=md_lo / md_lo=(pc) / pc=pc+1 + -- 4 pc=pc+md + -- + when "0110" => + -- increment the pc + pc_ctrl <= incr_pc; + next_state <= lbranch_state; + + -- + -- lbsr - long branch to subroutine (3 bytes) + -- 6809 => 9 cycles + -- cpu09 => 6 cycles + -- 1 op=(pc) /pc=pc+1 + -- 2 md_hi=sign(pc) / md_lo=(pc) / pc=pc+1 / sp=sp-1 + -- 3 md_hi=md_lo / md_lo=(pc) / pc=pc+1 + -- 4 (sp)= pc_lo / sp=sp-1 / pc=pc + -- 5 (sp)=pc_hi / pc=pc + -- 6 pc=pc+md + -- + when "0111" => + -- pre decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + sp_ctrl <= load_sp; + -- increment the pc + pc_ctrl <= incr_pc; + next_state <= lbranch_state; + + -- + -- Decimal Adjust Accumulator + -- + when "1001" => -- daa + left_ctrl <= acca_left; + right_ctrl <= accb_right; + alu_ctrl <= alu_daa; + cc_ctrl <= load_cc; + acca_ctrl <= load_acca; + lic <= '1'; + next_state <= fetch_state; + + -- + -- OR Condition Codes + -- + when "1010" => -- orcc + -- increment the pc + pc_ctrl <= incr_pc; + next_state <= orcc_state; + + -- + -- AND Condition Codes + -- + when "1100" => -- andcc + -- increment the pc + pc_ctrl <= incr_pc; + next_state <= andcc_state; + + -- + -- Sign Extend + -- + when "1101" => -- sex + left_ctrl <= accb_left; + right_ctrl <= zero_right; + alu_ctrl <= alu_sex; + cc_ctrl <= load_cc; + acca_ctrl <= load_hi_acca; + lic <= '1'; + next_state <= fetch_state; + + -- + -- Exchange Registers + -- + when "1110" => -- exg + -- increment the pc + pc_ctrl <= incr_pc; + next_state <= exg_state; + + -- + -- Transfer Registers + -- + when "1111" => -- tfr + -- increment the pc + pc_ctrl <= incr_pc; + next_state <= tfr_state; + + when others => + -- increment the pc + pc_ctrl <= incr_pc; + lic <= '1'; + next_state <= fetch_state; + end case; + + -- + -- Short branch conditional + -- 6809 => always 3 cycles + -- cpu09 => always = 3 cycles + -- 1 op=(pc) / pc=pc+1 + -- 2 md_hi=sign(pc) / md_lo=(pc) / pc=pc+1 / test cc + -- 3 if cc tru pc=pc+md else pc=pc + -- + when "0010" => -- branch conditional + -- increment the pc + pc_ctrl <= incr_pc; + next_state <= sbranch_state; + + -- + -- Single byte stack operators + -- Do not advance PC + -- + when "0011" => + -- + -- lea - load effective address (2+ bytes) + -- 6809 => 4 cycles + addressing mode + -- cpu09 => 4 cycles + addressing mode + -- 1 op=(pc) / pc=pc+1 + -- 2 md_lo=(pc) / pc=pc+1 + -- 3 calculate ea + -- 4 ix/iy/sp/up = ea + -- + case op_code(3 downto 0) is + when "0000" | -- leax + "0001" | -- leay + "0010" | -- leas + "0011" => -- leau + -- advance PC + pc_ctrl <= incr_pc; + st_ctrl <= push_st; + return_state <= lea_state; + next_state <= indexed_state; + + -- + -- pshs - push registers onto sp stack + -- 6809 => 5 cycles + registers + -- cpu09 => 3 cycles + registers + -- 1 op=(pc) / pc=pc+1 + -- 2 ea_lo=(pc) / pc=pc+1 + -- 3 if ea(7 downto 0) != "00000000" then sp=sp-1 + -- 4 if ea(7) = 1 (sp)=pcl, sp=sp-1 + -- 5 if ea(7) = 1 (sp)=pch + -- if ea(6 downto 0) != "0000000" then sp=sp-1 + -- 6 if ea(6) = 1 (sp)=upl, sp=sp-1 + -- 7 if ea(6) = 1 (sp)=uph + -- if ea(5 downto 0) != "000000" then sp=sp-1 + -- 8 if ea(5) = 1 (sp)=iyl, sp=sp-1 + -- 9 if ea(5) = 1 (sp)=iyh + -- if ea(4 downto 0) != "00000" then sp=sp-1 + -- 10 if ea(4) = 1 (sp)=ixl, sp=sp-1 + -- 11 if ea(4) = 1 (sp)=ixh + -- if ea(3 downto 0) != "0000" then sp=sp-1 + -- 12 if ea(3) = 1 (sp)=dp + -- if ea(2 downto 0) != "000" then sp=sp-1 + -- 13 if ea(2) = 1 (sp)=accb + -- if ea(1 downto 0) != "00" then sp=sp-1 + -- 14 if ea(1) = 1 (sp)=acca + -- if ea(0 downto 0) != "0" then sp=sp-1 + -- 15 if ea(0) = 1 (sp)=cc + -- + when "0100" => -- pshs + -- advance PC + pc_ctrl <= incr_pc; + next_state <= pshs_state; + + -- + -- puls - pull registers of sp stack + -- 6809 => 5 cycles + registers + -- cpu09 => 3 cycles + registers + -- + when "0101" => -- puls + -- advance PC + pc_ctrl <= incr_pc; + next_state <= puls_state; + + -- + -- pshu - push registers onto up stack + -- 6809 => 5 cycles + registers + -- cpu09 => 3 cycles + registers + -- + when "0110" => -- pshu + -- advance PC + pc_ctrl <= incr_pc; + next_state <= pshu_state; + + -- + -- pulu - pull registers of up stack + -- 6809 => 5 cycles + registers + -- cpu09 => 3 cycles + registers + -- + when "0111" => -- pulu + -- advance PC + pc_ctrl <= incr_pc; + next_state <= pulu_state; + + -- + -- rts - return from subroutine + -- 6809 => 5 cycles + -- cpu09 => 4 cycles + -- 1 op=(pc) / pc=pc+1 + -- 2 decode op + -- 3 pc_hi = (sp) / sp=sp+1 + -- 4 pc_lo = (sp) / sp=sp+1 + -- + when "1001" => + next_state <= pull_return_hi_state; + + -- + -- ADD accb to index register + -- *** Note: this is an unsigned addition. + -- does not affect any condition codes + -- 6809 => 3 cycles + -- cpu09 => 2 cycles + -- 1 op=(pc) / pc=pc+1 + -- 2 alu_left=ix / alu_right=accb / ix=alu_out / pc=pc + -- + when "1010" => -- abx + lic <= '1'; + left_ctrl <= ix_left; + right_ctrl <= accb_right; + alu_ctrl <= alu_abx; + ix_ctrl <= load_ix; + next_state <= fetch_state; + + -- + -- Return From Interrupt + -- + when "1011" => -- rti + next_state <= rti_cc_state; + + -- + -- CWAI + -- + when "1100" => -- cwai #$ + -- pre decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + sp_ctrl <= load_sp; + -- increment pc + pc_ctrl <= incr_pc; + next_state <= cwai_state; + + -- + -- MUL Multiply + -- + when "1101" => -- mul + next_state <= mul_state; + + -- + -- SWI Software Interrupt + -- + when "1111" => -- swi + -- predecrement SP + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + sp_ctrl <= load_sp; + iv_ctrl <= swi_iv; + st_ctrl <= push_st; + return_state <= int_swimask_state; + next_state <= int_entire_state; + + when others => + lic <= '1'; + next_state <= fetch_state; + + end case; + -- + -- Accumulator A Single operand + -- source = acca, dest = acca + -- Do not advance PC + -- Typically 2 cycles 1 bytes + -- 1 opcode fetch + -- 2 post byte fetch / instruction decode + -- Note that there is no post byte + -- so do not advance PC in decode cycle + -- Re-run opcode fetch cycle after decode + -- + when "0100" => -- acca single op + left_ctrl <= acca_left; + case op_code(3 downto 0) is + + when "0000" => -- neg + right_ctrl <= zero_right; + alu_ctrl <= alu_neg; + acca_ctrl <= load_acca; + cc_ctrl <= load_cc; + + when "0011" => -- com + right_ctrl <= zero_right; + alu_ctrl <= alu_com; + acca_ctrl <= load_acca; + cc_ctrl <= load_cc; + + when "0100" => -- lsr + right_ctrl <= zero_right; + alu_ctrl <= alu_lsr8; + acca_ctrl <= load_acca; + cc_ctrl <= load_cc; + + when "0110" => -- ror + right_ctrl <= zero_right; + alu_ctrl <= alu_ror8; + acca_ctrl <= load_acca; + cc_ctrl <= load_cc; + + when "0111" => -- asr + right_ctrl <= zero_right; + alu_ctrl <= alu_asr8; + acca_ctrl <= load_acca; + cc_ctrl <= load_cc; + + when "1000" => -- asl + right_ctrl <= zero_right; + alu_ctrl <= alu_asl8; + acca_ctrl <= load_acca; + cc_ctrl <= load_cc; + + when "1001" => -- rol + right_ctrl <= zero_right; + alu_ctrl <= alu_rol8; + acca_ctrl <= load_acca; + cc_ctrl <= load_cc; + + when "1010" => -- dec + right_ctrl <= one_right; + alu_ctrl <= alu_dec; + acca_ctrl <= load_acca; + cc_ctrl <= load_cc; + + when "1011" => -- undefined + right_ctrl <= zero_right; + alu_ctrl <= alu_nop; + acca_ctrl <= latch_acca; + cc_ctrl <= latch_cc; + + when "1100" => -- inc + right_ctrl <= one_right; + alu_ctrl <= alu_inc; + acca_ctrl <= load_acca; + cc_ctrl <= load_cc; + + when "1101" => -- tst + right_ctrl <= zero_right; + alu_ctrl <= alu_st8; + acca_ctrl <= latch_acca; + cc_ctrl <= load_cc; + + when "1110" => -- jmp (not defined) + right_ctrl <= zero_right; + alu_ctrl <= alu_nop; + acca_ctrl <= latch_acca; + cc_ctrl <= latch_cc; + + when "1111" => -- clr + right_ctrl <= zero_right; + alu_ctrl <= alu_clr; + acca_ctrl <= load_acca; + cc_ctrl <= load_cc; + + when others => + right_ctrl <= zero_right; + alu_ctrl <= alu_nop; + acca_ctrl <= latch_acca; + cc_ctrl <= latch_cc; + + end case; + lic <= '1'; + next_state <= fetch_state; + + -- + -- Single Operand accb + -- source = accb, dest = accb + -- Typically 2 cycles 1 bytes + -- 1 opcode fetch + -- 2 post byte fetch / instruction decode + -- Note that there is no post byte + -- so do not advance PC in decode cycle + -- Re-run opcode fetch cycle after decode + -- + when "0101" => + left_ctrl <= accb_left; + case op_code(3 downto 0) is + when "0000" => -- neg + right_ctrl <= zero_right; + alu_ctrl <= alu_neg; + accb_ctrl <= load_accb; + cc_ctrl <= load_cc; + + when "0011" => -- com + right_ctrl <= zero_right; + alu_ctrl <= alu_com; + accb_ctrl <= load_accb; + cc_ctrl <= load_cc; + + when "0100" => -- lsr + right_ctrl <= zero_right; + alu_ctrl <= alu_lsr8; + accb_ctrl <= load_accb; + cc_ctrl <= load_cc; + + when "0110" => -- ror + right_ctrl <= zero_right; + alu_ctrl <= alu_ror8; + accb_ctrl <= load_accb; + cc_ctrl <= load_cc; + + when "0111" => -- asr + right_ctrl <= zero_right; + alu_ctrl <= alu_asr8; + accb_ctrl <= load_accb; + cc_ctrl <= load_cc; + + when "1000" => -- asl + right_ctrl <= zero_right; + alu_ctrl <= alu_asl8; + accb_ctrl <= load_accb; + cc_ctrl <= load_cc; + + when "1001" => -- rol + right_ctrl <= zero_right; + alu_ctrl <= alu_rol8; + accb_ctrl <= load_accb; + cc_ctrl <= load_cc; + + when "1010" => -- dec + right_ctrl <= one_right; + alu_ctrl <= alu_dec; + accb_ctrl <= load_accb; + cc_ctrl <= load_cc; + + when "1011" => -- undefined + right_ctrl <= zero_right; + alu_ctrl <= alu_nop; + accb_ctrl <= latch_accb; + cc_ctrl <= latch_cc; + + when "1100" => -- inc + right_ctrl <= one_right; + alu_ctrl <= alu_inc; + accb_ctrl <= load_accb; + cc_ctrl <= load_cc; + + when "1101" => -- tst + right_ctrl <= zero_right; + alu_ctrl <= alu_st8; + accb_ctrl <= latch_accb; + cc_ctrl <= load_cc; + + when "1110" => -- jmp (undefined) + right_ctrl <= zero_right; + alu_ctrl <= alu_nop; + accb_ctrl <= latch_accb; + cc_ctrl <= latch_cc; + + when "1111" => -- clr + right_ctrl <= zero_right; + alu_ctrl <= alu_clr; + accb_ctrl <= load_accb; + cc_ctrl <= load_cc; + + when others => + right_ctrl <= zero_right; + alu_ctrl <= alu_nop; + accb_ctrl <= latch_accb; + cc_ctrl <= latch_cc; + end case; + lic <= '1'; + next_state <= fetch_state; + + -- + -- Single operand indexed + -- Two byte instruction so advance PC + -- EA should hold index offset + -- + when "0110" => -- indexed single op + -- increment the pc + pc_ctrl <= incr_pc; + st_ctrl <= push_st; + + case op_code(3 downto 0) is + when "1110" => -- jmp + return_state <= jmp_state; + + when "1111" => -- clr + return_state <= single_op_exec_state; + + when others => + return_state <= single_op_read_state; + + end case; + next_state <= indexed_state; + + -- + -- Single operand extended addressing + -- three byte instruction so advance the PC + -- Low order EA holds high order address + -- + when "0111" => -- extended single op + -- increment PC + pc_ctrl <= incr_pc; + st_ctrl <= push_st; + + case op_code(3 downto 0) is + when "1110" => -- jmp + return_state <= jmp_state; + + when "1111" => -- clr + return_state <= single_op_exec_state; + + when others => + return_state <= single_op_read_state; + + end case; + next_state <= extended_state; + + when "1000" => -- acca immediate + -- increment the pc + pc_ctrl <= incr_pc; + + case op_code(3 downto 0) is + when "0011" | -- subd # + "1100" | -- cmpx # + "1110" => -- ldx # + next_state <= imm16_state; + + -- + -- bsr offset - Branch to subroutine (2 bytes) + -- 6809 => 7 cycles + -- cpu09 => 5 cycles + -- 1 op=(pc) / pc=pc+1 + -- 2 md_hi=sign(pc) / md_lo=(pc) / sp=sp-1 / pc=pc+1 + -- 3 (sp)=pc_lo / sp=sp-1 + -- 4 (sp)=pc_hi + -- 5 pc=pc+md + -- + when "1101" => -- bsr + -- pre decrement SP + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + sp_ctrl <= load_sp; + -- + st_ctrl <= push_st; + return_state <= sbranch_state; + next_state <= push_return_lo_state; + + when others => + lic <= '1'; + next_state <= fetch_state; + + end case; + + when "1001" => -- acca direct + -- increment the pc + pc_ctrl <= incr_pc; + case op_code(3 downto 0) is + when "0011" | -- subd + "1100" | -- cmpx + "1110" => -- ldx + next_state <= dual_op_read16_state; + + when "0111" => -- sta direct + next_state <= dual_op_write8_state; + + -- + -- jsr direct - Jump to subroutine in direct page (2 bytes) + -- 6809 => 7 cycles + -- cpu09 => 5 cycles + -- 1 op=(pc) / pc=pc+1 + -- 2 ea_hi=0 / ea_lo=(pc) / sp=sp-1 / pc=pc+1 + -- 3 (sp)=pc_lo / sp=sp-1 + -- 4 (sp)=pc_hi + -- 5 pc=ea + -- + when "1101" => -- jsr direct + -- pre decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + sp_ctrl <= load_sp; + -- + st_ctrl <= push_st; + return_state <= jmp_state; + next_state <= push_return_lo_state; + + + when "1111" => -- stx direct + -- idle ALU + left_ctrl <= ix_left; + right_ctrl <= zero_right; + alu_ctrl <= alu_nop; + cc_ctrl <= latch_cc; + sp_ctrl <= latch_sp; + next_state <= dual_op_write16_state; + + when others => + next_state <= dual_op_read8_state; + + end case; + + when "1010" => -- acca indexed + -- increment the pc + pc_ctrl <= incr_pc; + case op_code(3 downto 0) is + when "0011" | -- subd + "1100" | -- cmpx + "1110" => -- ldx + st_ctrl <= push_st; + return_state <= dual_op_read16_state; + next_state <= indexed_state; + + when "0111" => -- staa ,x + st_ctrl <= push_st; + return_state <= dual_op_write8_state; + next_state <= indexed_state; + + when "1101" => -- jsr ,x + -- DO NOT pre decrement SP + st_ctrl <= push_st; + return_state <= jsr_state; + next_state <= indexed_state; + + when "1111" => -- stx ,x + st_ctrl <= push_st; + return_state <= dual_op_write16_state; + next_state <= indexed_state; + + when others => + st_ctrl <= push_st; + return_state <= dual_op_read8_state; + next_state <= indexed_state; + + end case; + + when "1011" => -- acca extended + -- increment the pc + pc_ctrl <= incr_pc; + case op_code(3 downto 0) is + when "0011" | -- subd + "1100" | -- cmpx + "1110" => -- ldx + st_ctrl <= push_st; + return_state <= dual_op_read16_state; + next_state <= extended_state; + + when "0111" => -- staa > + st_ctrl <= push_st; + return_state <= dual_op_write8_state; + next_state <= extended_state; + + when "1101" => -- jsr >extended + -- DO NOT pre decrement sp + st_ctrl <= push_st; + return_state <= jsr_state; + next_state <= extended_state; + + when "1111" => -- stx > + st_ctrl <= push_st; + return_state <= dual_op_write16_state; + next_state <= extended_state; + + when others => + st_ctrl <= push_st; + return_state <= dual_op_read8_state; + next_state <= extended_state; + + end case; + + when "1100" => -- accb immediate + -- increment the pc + pc_ctrl <= incr_pc; + case op_code(3 downto 0) is + when "0011" | -- addd # + "1100" | -- ldd # + "1110" => -- ldu # + next_state <= imm16_state; + + when others => + lic <= '1'; + next_state <= fetch_state; + + end case; + + when "1101" => -- accb direct + -- increment the pc + pc_ctrl <= incr_pc; + case op_code(3 downto 0) is + when "0011" | -- addd + "1100" | -- ldd + "1110" => -- ldu + next_state <= dual_op_read16_state; + + when "0111" => -- stab direct + next_state <= dual_op_write8_state; + + when "1101" => -- std direct + next_state <= dual_op_write16_state; + + when "1111" => -- stu direct + next_state <= dual_op_write16_state; + + when others => + next_state <= dual_op_read8_state; + + end case; + + when "1110" => -- accb indexed + -- increment the pc + pc_ctrl <= incr_pc; + case op_code(3 downto 0) is + when "0011" | -- addd + "1100" | -- ldd + "1110" => -- ldu + st_ctrl <= push_st; + return_state <= dual_op_read16_state; + next_state <= indexed_state; + + when "0111" => -- stab indexed + st_ctrl <= push_st; + return_state <= dual_op_write8_state; + next_state <= indexed_state; + + when "1101" => -- std indexed + st_ctrl <= push_st; + return_state <= dual_op_write16_state; + next_state <= indexed_state; + + when "1111" => -- stu indexed + st_ctrl <= push_st; + return_state <= dual_op_write16_state; + next_state <= indexed_state; + + when others => + st_ctrl <= push_st; + return_state <= dual_op_read8_state; + next_state <= indexed_state; + + end case; + + when "1111" => -- accb extended + -- increment the pc + pc_ctrl <= incr_pc; + case op_code(3 downto 0) is + when "0011" | -- addd + "1100" | -- ldd + "1110" => -- ldu + st_ctrl <= push_st; + return_state <= dual_op_read16_state; + next_state <= extended_state; + + when "0111" => -- stab extended + st_ctrl <= push_st; + return_state <= dual_op_write8_state; + next_state <= extended_state; + + when "1101" => -- std extended + st_ctrl <= push_st; + return_state <= dual_op_write16_state; + next_state <= extended_state; + + when "1111" => -- stu extended + st_ctrl <= push_st; + return_state <= dual_op_write16_state; + next_state <= extended_state; + + when others => + st_ctrl <= push_st; + return_state <= dual_op_read8_state; + next_state <= extended_state; + end case; + -- + -- not sure why I need this + -- + when others => + lic <= '1'; + next_state <= fetch_state; + end case; + + -- + -- Here to decode prefix 2 instruction + -- and fetch next byte of intruction + -- whether it be necessary or not + -- + when decode2_state => + -- fetch first byte of address or immediate data + ea_ctrl <= fetch_first_ea; + md_ctrl <= fetch_first_md; + addr_ctrl <= fetch_ad; + case op_code(7 downto 4) is + -- + -- lbcc -- long branch conditional + -- 6809 => branch 6 cycles, no branch 5 cycles + -- cpu09 => always 5 cycles + -- 1 pre=(pc) / pc=pc+1 + -- 2 op=(pc) / pc=pc+1 + -- 3 md_hi=sign(pc) / md_lo=(pc) / pc=pc+1 + -- 4 md_hi=md_lo / md_lo=(pc) / pc=pc+1 + -- 5 if cond pc=pc+md else pc=pc + -- + when "0010" => + -- increment the pc + pc_ctrl <= incr_pc; + next_state <= lbranch_state; + + -- + -- Single byte stack operators + -- Do not advance PC + -- + when "0011" => + case op_code(3 downto 0) is + when "1111" => -- swi 2 + -- predecrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + sp_ctrl <= load_sp; + iv_ctrl <= swi2_iv; + st_ctrl <= push_st; + return_state <= vect_hi_state; + next_state <= int_entire_state; + + when others => + lic <= '1'; + next_state <= fetch_state; + end case; + + when "1000" => -- acca immediate + -- increment the pc + pc_ctrl <= incr_pc; + case op_code(3 downto 0) is + when "0011" | -- cmpd # + "1100" | -- cmpy # + "1110" => -- ldy # + next_state <= imm16_state; + + when others => + lic <= '1'; + next_state <= fetch_state; + + end case; + + when "1001" => -- acca direct + -- increment the pc + pc_ctrl <= incr_pc; + case op_code(3 downto 0) is + when "0011" | -- cmpd < + "1100" | -- cmpy < + "1110" => -- ldy < + next_state <= dual_op_read16_state; + + when "1111" => -- sty < + next_state <= dual_op_write16_state; + + when others => + lic <= '1'; + next_state <= fetch_state; + + end case; + + when "1010" => -- acca indexed + -- increment the pc + pc_ctrl <= incr_pc; + case op_code(3 downto 0) is + when "0011" | -- cmpd ,ind + "1100" | -- cmpy ,ind + "1110" => -- ldy ,ind + st_ctrl <= push_st; + return_state <= dual_op_read16_state; + next_state <= indexed_state; + + when "1111" => -- sty ,ind + st_ctrl <= push_st; + return_state <= dual_op_write16_state; + next_state <= indexed_state; + + when others => + lic <= '1'; + next_state <= fetch_state; + end case; + + when "1011" => -- acca extended + -- increment the pc + pc_ctrl <= incr_pc; + case op_code(3 downto 0) is + when "0011" | -- cmpd < + "1100" | -- cmpy < + "1110" => -- ldy < + st_ctrl <= push_st; + return_state <= dual_op_read16_state; + next_state <= extended_state; + + when "1111" => -- sty > + st_ctrl <= push_st; + return_state <= dual_op_write16_state; + next_state <= extended_state; + + when others => + lic <= '1'; + next_state <= fetch_state; + + end case; + + when "1100" => -- accb immediate + -- increment the pc + pc_ctrl <= incr_pc; + case op_code(3 downto 0) is + when "0011" | -- undef # + "1100" | -- undef # + "1110" => -- lds # + next_state <= imm16_state; + + when others => + next_state <= fetch_state; + + end case; + + when "1101" => -- accb direct + -- increment the pc + pc_ctrl <= incr_pc; + case op_code(3 downto 0) is + when "0011" | -- undef < + "1100" | -- undef < + "1110" => -- lds < + next_state <= dual_op_read16_state; + + when "1111" => -- sts < + next_state <= dual_op_write16_state; + + when others => + lic <= '1'; + next_state <= fetch_state; + + end case; + + when "1110" => -- accb indexed + -- increment the pc + pc_ctrl <= incr_pc; + case op_code(3 downto 0) is + when "0011" | -- undef ,ind + "1100" | -- undef ,ind + "1110" => -- lds ,ind + st_ctrl <= push_st; + return_state <= dual_op_read16_state; + next_state <= indexed_state; + + when "1111" => -- sts ,ind + st_ctrl <= push_st; + return_state <= dual_op_write16_state; + next_state <= indexed_state; + + when others => + lic <= '1'; + next_state <= fetch_state; + + end case; + + when "1111" => -- accb extended + -- increment the pc + pc_ctrl <= incr_pc; + case op_code(3 downto 0) is + when "0011" | -- undef > + "1100" | -- undef > + "1110" => -- lds > + st_ctrl <= push_st; + return_state <= dual_op_read16_state; + next_state <= extended_state; + + when "1111" => -- sts > + st_ctrl <= push_st; + return_state <= dual_op_write16_state; + next_state <= extended_state; + + when others => + lic <= '1'; + next_state <= fetch_state; + end case; + + when others => + lic <= '1'; + next_state <= fetch_state; + end case; + -- + -- Here to decode instruction + -- and fetch next byte of intruction + -- whether it be necessary or not + -- + when decode3_state => + ea_ctrl <= fetch_first_ea; + md_ctrl <= fetch_first_md; + addr_ctrl <= fetch_ad; + dout_ctrl <= md_lo_dout; + case op_code(7 downto 4) is + -- + -- Single byte stack operators + -- Do not advance PC + -- + when "0011" => + case op_code(3 downto 0) is + when "1111" => -- swi3 + -- predecrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + sp_ctrl <= load_sp; + iv_ctrl <= swi3_iv; + st_ctrl <= push_st; + return_state <= vect_hi_state; + next_state <= int_entire_state; + when others => + lic <= '1'; + next_state <= fetch_state; + end case; + + when "1000" => -- acca immediate + -- increment the pc + pc_ctrl <= incr_pc; + case op_code(3 downto 0) is + when "0011" | -- cmpu # + "1100" | -- cmps # + "1110" => -- undef # + next_state <= imm16_state; + when others => + lic <= '1'; + next_state <= fetch_state; + end case; + + when "1001" => -- acca direct + -- increment the pc + pc_ctrl <= incr_pc; + case op_code(3 downto 0) is + when "0011" | -- cmpu < + "1100" | -- cmps < + "1110" => -- undef < + next_state <= dual_op_read16_state; + + when others => + lic <= '1'; + next_state <= fetch_state; + + end case; + + when "1010" => -- acca indexed + -- increment the pc + pc_ctrl <= incr_pc; + case op_code(3 downto 0) is + when "0011" | -- cmpu ,X + "1100" | -- cmps ,X + "1110" => -- undef ,X + st_ctrl <= push_st; + return_state <= dual_op_read16_state; + next_state <= indexed_state; + + when others => + lic <= '1'; + next_state <= fetch_state; + + end case; + + when "1011" => -- acca extended + -- increment the pc + pc_ctrl <= incr_pc; + case op_code(3 downto 0) is + when "0011" | -- cmpu > + "1100" | -- cmps > + "1110" => -- undef > + st_ctrl <= push_st; + return_state <= dual_op_read16_state; + next_state <= extended_state; + when others => + lic <= '1'; + next_state <= fetch_state; + end case; + + when others => + lic <= '1'; + next_state <= fetch_state; + end case; + + -- + -- here if ea holds low byte + -- Direct + -- Extended + -- Indexed + -- read memory location + -- + when single_op_read_state => + -- read memory into md + md_ctrl <= fetch_first_md; + addr_ctrl <= read_ad; + dout_ctrl <= md_lo_dout; + next_state <= single_op_exec_state; + + when single_op_exec_state => + case op_code(3 downto 0) is + when "0000" => -- neg + left_ctrl <= md_left; + right_ctrl <= zero_right; + alu_ctrl <= alu_neg; + cc_ctrl <= load_cc; + md_ctrl <= load_md; + next_state <= single_op_write_state; + when "0011" => -- com + left_ctrl <= md_left; + right_ctrl <= zero_right; + alu_ctrl <= alu_com; + cc_ctrl <= load_cc; + md_ctrl <= load_md; + next_state <= single_op_write_state; + when "0100" => -- lsr + left_ctrl <= md_left; + right_ctrl <= zero_right; + alu_ctrl <= alu_lsr8; + cc_ctrl <= load_cc; + md_ctrl <= load_md; + next_state <= single_op_write_state; + when "0110" => -- ror + left_ctrl <= md_left; + right_ctrl <= zero_right; + alu_ctrl <= alu_ror8; + cc_ctrl <= load_cc; + md_ctrl <= load_md; + next_state <= single_op_write_state; + when "0111" => -- asr + left_ctrl <= md_left; + right_ctrl <= zero_right; + alu_ctrl <= alu_asr8; + cc_ctrl <= load_cc; + md_ctrl <= load_md; + next_state <= single_op_write_state; + when "1000" => -- asl + left_ctrl <= md_left; + right_ctrl <= zero_right; + alu_ctrl <= alu_asl8; + cc_ctrl <= load_cc; + md_ctrl <= load_md; + next_state <= single_op_write_state; + when "1001" => -- rol + left_ctrl <= md_left; + right_ctrl <= zero_right; + alu_ctrl <= alu_rol8; + cc_ctrl <= load_cc; + md_ctrl <= load_md; + next_state <= single_op_write_state; + when "1010" => -- dec + left_ctrl <= md_left; + right_ctrl <= one_right; + alu_ctrl <= alu_dec; + cc_ctrl <= load_cc; + md_ctrl <= load_md; + next_state <= single_op_write_state; + when "1011" => -- undefined + lic <= '1'; + next_state <= fetch_state; + when "1100" => -- inc + left_ctrl <= md_left; + right_ctrl <= one_right; + alu_ctrl <= alu_inc; + cc_ctrl <= load_cc; + md_ctrl <= load_md; + next_state <= single_op_write_state; + when "1101" => -- tst + left_ctrl <= md_left; + right_ctrl <= zero_right; + alu_ctrl <= alu_st8; + cc_ctrl <= load_cc; + lic <= '1'; + next_state <= fetch_state; + when "1110" => -- jmp + left_ctrl <= md_left; + right_ctrl <= zero_right; + alu_ctrl <= alu_ld16; + pc_ctrl <= load_pc; + lic <= '1'; + next_state <= fetch_state; + when "1111" => -- clr + left_ctrl <= md_left; + right_ctrl <= zero_right; + alu_ctrl <= alu_clr; + cc_ctrl <= load_cc; + md_ctrl <= load_md; + next_state <= single_op_write_state; + when others => + lic <= '1'; + next_state <= fetch_state; + end case; + -- + -- single operand 8 bit write + -- Write low 8 bits of ALU output + -- EA holds address + -- MD holds data + -- + when single_op_write_state => + -- write ALU low byte output + addr_ctrl <= write_ad; + dout_ctrl <= md_lo_dout; + lic <= '1'; + next_state <= fetch_state; + + -- + -- here if ea holds address of low byte + -- read memory location + -- + when dual_op_read8_state => + -- read first data byte from ea + md_ctrl <= fetch_first_md; + addr_ctrl <= read_ad; + lic <= '1'; + next_state <= fetch_state; + + -- + -- Here to read a 16 bit value into MD + -- pointed to by the EA register + -- The first byte is read + -- and the EA is incremented + -- + when dual_op_read16_state => + -- increment the effective address + left_ctrl <= ea_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + ea_ctrl <= load_ea; + -- read the high byte of the 16 bit data + md_ctrl <= fetch_first_md; + addr_ctrl <= read_ad; + next_state <= dual_op_read16_2_state; + + -- + -- here to read the second byte + -- pointed to by EA into MD + -- + when dual_op_read16_2_state => + -- read the low byte of the 16 bit data + md_ctrl <= fetch_next_md; + addr_ctrl <= read_ad; + lic <= '1'; + next_state <= fetch_state; + + -- + -- 16 bit Write state + -- EA hold address of memory to write to + -- Advance the effective address in ALU + -- decode op_code to determine which + -- register to write + -- + when dual_op_write16_state => + -- increment the effective address + left_ctrl <= ea_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + ea_ctrl <= load_ea; + -- write the ALU hi byte at ea + addr_ctrl <= write_ad; + if op_code(6) = '0' then + case op_code(3 downto 0) is + when "1111" => -- stx / sty + case pre_code is + when "00010000" => -- page 2 -- sty + dout_ctrl <= iy_hi_dout; + when others => -- page 1 -- stx + dout_ctrl <= ix_hi_dout; + end case; + when others => + dout_ctrl <= md_hi_dout; + end case; + else + case op_code(3 downto 0) is + when "1101" => -- std + dout_ctrl <= acca_dout; -- acca is high byte of ACCD + when "1111" => -- stu / sts + case pre_code is + when "00010000" => -- page 2 -- sts + dout_ctrl <= sp_hi_dout; + when others => -- page 1 -- stu + dout_ctrl <= up_hi_dout; + end case; + when others => + dout_ctrl <= md_hi_dout; + end case; + end if; + next_state <= dual_op_write8_state; + + -- + -- Dual operand 8 bit write + -- Write 8 bit accumulator + -- or low byte of 16 bit register + -- EA holds address + -- decode opcode to determine + -- which register to apply to the bus + -- Also set the condition codes here + -- + when dual_op_write8_state => + if op_code(6) = '0' then + case op_code(3 downto 0) is + when "0111" => -- sta + dout_ctrl <= acca_dout; + when "1111" => -- stx / sty + case pre_code is + when "00010000" => -- page 2 -- sty + dout_ctrl <= iy_lo_dout; + when others => -- page 1 -- stx + dout_ctrl <= ix_lo_dout; + end case; + when others => + dout_ctrl <= md_lo_dout; + end case; + else + case op_code(3 downto 0) is + when "0111" => -- stb + dout_ctrl <= accb_dout; + when "1101" => -- std + dout_ctrl <= accb_dout; -- accb is low byte of accd + when "1111" => -- stu / sts + case pre_code is + when "00010000" => -- page 2 -- sts + dout_ctrl <= sp_lo_dout; + when others => -- page 1 -- stu + dout_ctrl <= up_lo_dout; + end case; + when others => + dout_ctrl <= md_lo_dout; + end case; + end if; + -- write ALU low byte output + addr_ctrl <= write_ad; + lic <= '1'; + next_state <= fetch_state; + + -- + -- 16 bit immediate addressing mode + -- + when imm16_state => + -- increment pc + pc_ctrl <= incr_pc; + -- fetch next immediate byte + md_ctrl <= fetch_next_md; + addr_ctrl <= fetch_ad; + lic <= '1'; + next_state <= fetch_state; + + -- + -- md & ea holds 8 bit index offset + -- calculate the effective memory address + -- using the alu + -- + when indexed_state => + -- + -- decode indexing mode + -- + if md(7) = '0' then + case md(6 downto 5) is + when "00" => + left_ctrl <= ix_left; + when "01" => + left_ctrl <= iy_left; + when "10" => + left_ctrl <= up_left; + when others => + -- when "11" => + left_ctrl <= sp_left; + end case; + right_ctrl <= md_sign5_right; + alu_ctrl <= alu_add16; + ea_ctrl <= load_ea; + next_state <= saved_state; + + else + case md(3 downto 0) is + when "0000" => -- ,R+ + case md(6 downto 5) is + when "00" => + left_ctrl <= ix_left; + when "01" => + left_ctrl <= iy_left; + when "10" => + left_ctrl <= up_left; + when others => + left_ctrl <= sp_left; + end case; + -- + right_ctrl <= zero_right; + alu_ctrl <= alu_add16; + ea_ctrl <= load_ea; + next_state <= postincr1_state; + + when "0001" => -- ,R++ + case md(6 downto 5) is + when "00" => + left_ctrl <= ix_left; + when "01" => + left_ctrl <= iy_left; + when "10" => + left_ctrl <= up_left; + when others => + -- when "11" => + left_ctrl <= sp_left; + end case; + right_ctrl <= zero_right; + alu_ctrl <= alu_add16; + ea_ctrl <= load_ea; + next_state <= postincr2_state; + + when "0010" => -- ,-R + case md(6 downto 5) is + when "00" => + left_ctrl <= ix_left; + ix_ctrl <= load_ix; + when "01" => + left_ctrl <= iy_left; + iy_ctrl <= load_iy; + when "10" => + left_ctrl <= up_left; + up_ctrl <= load_up; + when others => + -- when "11" => + left_ctrl <= sp_left; + sp_ctrl <= load_sp; + end case; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + ea_ctrl <= load_ea; + next_state <= saved_state; + + when "0011" => -- ,--R + case md(6 downto 5) is + when "00" => + left_ctrl <= ix_left; + ix_ctrl <= load_ix; + when "01" => + left_ctrl <= iy_left; + iy_ctrl <= load_iy; + when "10" => + left_ctrl <= up_left; + up_ctrl <= load_up; + when others => + -- when "11" => + left_ctrl <= sp_left; + sp_ctrl <= load_sp; + end case; + right_ctrl <= two_right; + alu_ctrl <= alu_sub16; + ea_ctrl <= load_ea; + if md(4) = '0' then + next_state <= saved_state; + else + next_state <= indirect_state; + end if; + + when "0100" => -- ,R (zero offset) + case md(6 downto 5) is + when "00" => + left_ctrl <= ix_left; + when "01" => + left_ctrl <= iy_left; + when "10" => + left_ctrl <= up_left; + when others => + -- when "11" => + left_ctrl <= sp_left; + end case; + right_ctrl <= zero_right; + alu_ctrl <= alu_add16; + ea_ctrl <= load_ea; + if md(4) = '0' then + next_state <= saved_state; + else + next_state <= indirect_state; + end if; + + when "0101" => -- ACCB,R + case md(6 downto 5) is + when "00" => + left_ctrl <= ix_left; + when "01" => + left_ctrl <= iy_left; + when "10" => + left_ctrl <= up_left; + when others => + -- when "11" => + left_ctrl <= sp_left; + end case; + right_ctrl <= accb_right; + alu_ctrl <= alu_add16; + ea_ctrl <= load_ea; + if md(4) = '0' then + next_state <= saved_state; + else + next_state <= indirect_state; + end if; + + when "0110" => -- ACCA,R + case md(6 downto 5) is + when "00" => + left_ctrl <= ix_left; + when "01" => + left_ctrl <= iy_left; + when "10" => + left_ctrl <= up_left; + when others => + -- when "11" => + left_ctrl <= sp_left; + end case; + right_ctrl <= acca_right; + alu_ctrl <= alu_add16; + ea_ctrl <= load_ea; + if md(4) = '0' then + next_state <= saved_state; + else + next_state <= indirect_state; + end if; + + when "0111" => -- undefined + case md(6 downto 5) is + when "00" => + left_ctrl <= ix_left; + when "01" => + left_ctrl <= iy_left; + when "10" => + left_ctrl <= up_left; + when others => + -- when "11" => + left_ctrl <= sp_left; + end case; + right_ctrl <= zero_right; + alu_ctrl <= alu_add16; + ea_ctrl <= load_ea; + if md(4) = '0' then + next_state <= saved_state; + else + next_state <= indirect_state; + end if; + + when "1000" => -- offset8,R + md_ctrl <= fetch_first_md; -- pick up 8 bit offset + addr_ctrl <= fetch_ad; + pc_ctrl <= incr_pc; + next_state <= index8_state; + + when "1001" => -- offset16,R + md_ctrl <= fetch_first_md; -- pick up first byte of 16 bit offset + addr_ctrl <= fetch_ad; + pc_ctrl <= incr_pc; + next_state <= index16_state; + + when "1010" => -- undefined + case md(6 downto 5) is + when "00" => + left_ctrl <= ix_left; + when "01" => + left_ctrl <= iy_left; + when "10" => + left_ctrl <= up_left; + when others => + -- when "11" => + left_ctrl <= sp_left; + end case; + right_ctrl <= zero_right; + alu_ctrl <= alu_add16; + ea_ctrl <= load_ea; + -- + if md(4) = '0' then + next_state <= saved_state; + else + next_state <= indirect_state; + end if; + + when "1011" => -- ACCD,R + case md(6 downto 5) is + when "00" => + left_ctrl <= ix_left; + when "01" => + left_ctrl <= iy_left; + when "10" => + left_ctrl <= up_left; + when others => + -- when "11" => + left_ctrl <= sp_left; + end case; + right_ctrl <= accd_right; + alu_ctrl <= alu_add16; + ea_ctrl <= load_ea; + if md(4) = '0' then + next_state <= saved_state; + else + next_state <= indirect_state; + end if; + + when "1100" => -- offset8,PC + -- fetch 8 bit offset + md_ctrl <= fetch_first_md; + addr_ctrl <= fetch_ad; + pc_ctrl <= incr_pc; + next_state <= pcrel8_state; + + when "1101" => -- offset16,PC + -- fetch offset + md_ctrl <= fetch_first_md; + addr_ctrl <= fetch_ad; + pc_ctrl <= incr_pc; + next_state <= pcrel16_state; + + when "1110" => -- undefined + case md(6 downto 5) is + when "00" => + left_ctrl <= ix_left; + when "01" => + left_ctrl <= iy_left; + when "10" => + left_ctrl <= up_left; + when others => + -- when "11" => + left_ctrl <= sp_left; + end case; + right_ctrl <= zero_right; + alu_ctrl <= alu_add16; + ea_ctrl <= load_ea; + if md(4) = '0' then + next_state <= saved_state; + else + next_state <= indirect_state; + end if; + + when others => +-- when "1111" => -- [,address] + -- advance PC to pick up address + md_ctrl <= fetch_first_md; + addr_ctrl <= fetch_ad; + pc_ctrl <= incr_pc; + next_state <= indexaddr_state; + end case; + end if; + + -- load index register with ea plus one + when postincr1_state => + left_ctrl <= ea_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + case md(6 downto 5) is + when "00" => + ix_ctrl <= load_ix; + when "01" => + iy_ctrl <= load_iy; + when "10" => + up_ctrl <= load_up; + when others => + -- when "11" => + sp_ctrl <= load_sp; + end case; + -- return to previous state + if md(4) = '0' then + next_state <= saved_state; + else + next_state <= indirect_state; + end if; + + -- load index register with ea plus two + when postincr2_state => + -- increment register by two (address) + left_ctrl <= ea_left; + right_ctrl <= two_right; + alu_ctrl <= alu_add16; + case md(6 downto 5) is + when "00" => + ix_ctrl <= load_ix; + when "01" => + iy_ctrl <= load_iy; + when "10" => + up_ctrl <= load_up; + when others => + -- when "11" => + sp_ctrl <= load_sp; + end case; + -- return to previous state + if md(4) = '0' then + next_state <= saved_state; + else + next_state <= indirect_state; + end if; + -- + -- ea = index register + md (8 bit signed offset) + -- ea holds post byte + -- + when index8_state => + case ea(6 downto 5) is + when "00" => + left_ctrl <= ix_left; + when "01" => + left_ctrl <= iy_left; + when "10" => + left_ctrl <= up_left; + when others => + -- when "11" => + left_ctrl <= sp_left; + end case; + -- ea = index reg + md + right_ctrl <= md_sign8_right; + alu_ctrl <= alu_add16; + ea_ctrl <= load_ea; + -- return to previous state + if ea(4) = '0' then + next_state <= saved_state; + else + next_state <= indirect_state; + end if; + + -- fetch low byte of 16 bit indexed offset + when index16_state => + -- advance pc + pc_ctrl <= incr_pc; + -- fetch low byte + md_ctrl <= fetch_next_md; + addr_ctrl <= fetch_ad; + next_state <= index16_2_state; + + -- ea = index register + md (16 bit offset) + -- ea holds post byte + when index16_2_state => + case ea(6 downto 5) is + when "00" => + left_ctrl <= ix_left; + when "01" => + left_ctrl <= iy_left; + when "10" => + left_ctrl <= up_left; + when others => + -- when "11" => + left_ctrl <= sp_left; + end case; + -- ea = index reg + md + right_ctrl <= md_right; + alu_ctrl <= alu_add16; + ea_ctrl <= load_ea; + -- return to previous state + if ea(4) = '0' then + next_state <= saved_state; + else + next_state <= indirect_state; + end if; + -- + -- pc relative with 8 bit signed offest + -- md holds signed offset + -- + when pcrel8_state => + -- ea = pc + signed md + left_ctrl <= pc_left; + right_ctrl <= md_sign8_right; + alu_ctrl <= alu_add16; + ea_ctrl <= load_ea; + -- return to previous state + if ea(4) = '0' then + next_state <= saved_state; + else + next_state <= indirect_state; + end if; + + -- pc relative addressing with 16 bit offset + -- pick up the low byte of the offset in md + -- advance the pc + when pcrel16_state => + -- advance pc + pc_ctrl <= incr_pc; + -- fetch low byte + md_ctrl <= fetch_next_md; + addr_ctrl <= fetch_ad; + next_state <= pcrel16_2_state; + + -- pc relative with16 bit signed offest + -- md holds signed offset + when pcrel16_2_state => + -- ea = pc + md + left_ctrl <= pc_left; + right_ctrl <= md_right; + alu_ctrl <= alu_add16; + ea_ctrl <= load_ea; + -- return to previous state + if ea(4) = '0' then + next_state <= saved_state; + else + next_state <= indirect_state; + end if; + + -- indexed to address + -- pick up the low byte of the address + -- advance the pc + when indexaddr_state => + -- advance pc + pc_ctrl <= incr_pc; + -- fetch low byte + md_ctrl <= fetch_next_md; + addr_ctrl <= fetch_ad; + next_state <= indexaddr2_state; + + -- indexed to absolute address + -- md holds address + -- ea hold indexing mode byte + when indexaddr2_state => + -- ea = md + left_ctrl <= pc_left; + right_ctrl <= md_right; + alu_ctrl <= alu_ld16; + ea_ctrl <= load_ea; + -- return to previous state + if ea(4) = '0' then + next_state <= saved_state; + else + next_state <= indirect_state; + end if; + + -- + -- load md with high byte of indirect address + -- pointed to by ea + -- increment ea + -- + when indirect_state => + -- increment ea + left_ctrl <= ea_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + ea_ctrl <= load_ea; + -- fetch high byte + md_ctrl <= fetch_first_md; + addr_ctrl <= read_ad; + next_state <= indirect2_state; + -- + -- load md with low byte of indirect address + -- pointed to by ea + -- ea has previously been incremented + -- + when indirect2_state => + -- fetch high byte + md_ctrl <= fetch_next_md; + addr_ctrl <= read_ad; + dout_ctrl <= md_lo_dout; + next_state <= indirect3_state; + -- + -- complete idirect addressing + -- by loading ea with md + -- + when indirect3_state => + -- load ea with md + left_ctrl <= ea_left; + right_ctrl <= md_right; + alu_ctrl <= alu_ld16; + ea_ctrl <= load_ea; + -- return to previous state + next_state <= saved_state; + + -- + -- ea holds the low byte of the absolute address + -- Move ea low byte into ea high byte + -- load new ea low byte to for absolute 16 bit address + -- advance the program counter + -- + when extended_state => -- fetch ea low byte + -- increment pc + pc_ctrl <= incr_pc; + -- fetch next effective address bytes + ea_ctrl <= fetch_next_ea; + addr_ctrl <= fetch_ad; + -- return to previous state + next_state <= saved_state; + + when lea_state => -- here on load effective address + -- load index register with effective address + left_ctrl <= pc_left; + right_ctrl <= ea_right; + alu_ctrl <= alu_lea; + case op_code(3 downto 0) is + when "0000" => -- leax + cc_ctrl <= load_cc; + ix_ctrl <= load_ix; + when "0001" => -- leay + cc_ctrl <= load_cc; + iy_ctrl <= load_iy; + when "0010" => -- leas + sp_ctrl <= load_sp; + when "0011" => -- leau + up_ctrl <= load_up; + when others => + null; + end case; + lic <= '1'; + next_state <= fetch_state; + + -- + -- jump to subroutine + -- sp=sp-1 + -- call push_return_lo_state to save pc + -- return to jmp_state + -- + when jsr_state => + -- decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + sp_ctrl <= load_sp; + -- call push_return_state + st_ctrl <= push_st; + return_state <= jmp_state; + next_state <= push_return_lo_state; + + -- + -- Load pc with ea + -- (JMP) + -- + when jmp_state => + -- load PC with effective address + left_ctrl <= pc_left; + right_ctrl <= ea_right; + alu_ctrl <= alu_ld16; + pc_ctrl <= load_pc; + lic <= '1'; + next_state <= fetch_state; + + -- + -- long branch or branch to subroutine + -- pick up next md byte + -- md_hi = md_lo + -- md_lo = (pc) + -- pc=pc+1 + -- if a lbsr push return address + -- continue to sbranch_state + -- to evaluate conditional branches + -- + when lbranch_state => + pc_ctrl <= incr_pc; + -- fetch the next byte into md_lo + md_ctrl <= fetch_next_md; + addr_ctrl <= fetch_ad; + -- if lbsr - push return address + -- then continue on to short branch + if op_code = "00010111" then + st_ctrl <= push_st; + return_state <= sbranch_state; + next_state <= push_return_lo_state; + else + next_state <= sbranch_state; + end if; + + -- + -- here to execute conditional branch + -- short conditional branch md = signed 8 bit offset + -- long branch md = 16 bit offset + -- + when sbranch_state => + left_ctrl <= pc_left; + right_ctrl <= md_right; + alu_ctrl <= alu_add16; + -- Test condition for branch + if op_code(7 downto 4) = "0010" then -- conditional branch + case op_code(3 downto 0) is + when "0000" => -- bra + cond_true := (1 = 1); + when "0001" => -- brn + cond_true := (1 = 0); + when "0010" => -- bhi + cond_true := ((cc(CBIT) or cc(ZBIT)) = '0'); + when "0011" => -- bls + cond_true := ((cc(CBIT) or cc(ZBIT)) = '1'); + when "0100" => -- bcc/bhs + cond_true := (cc(CBIT) = '0'); + when "0101" => -- bcs/blo + cond_true := (cc(CBIT) = '1'); + when "0110" => -- bne + cond_true := (cc(ZBIT) = '0'); + when "0111" => -- beq + cond_true := (cc(ZBIT) = '1'); + when "1000" => -- bvc + cond_true := (cc(VBIT) = '0'); + when "1001" => -- bvs + cond_true := (cc(VBIT) = '1'); + when "1010" => -- bpl + cond_true := (cc(NBIT) = '0'); + when "1011" => -- bmi + cond_true := (cc(NBIT) = '1'); + when "1100" => -- bge + cond_true := ((cc(NBIT) xor cc(VBIT)) = '0'); + when "1101" => -- blt + cond_true := ((cc(NBIT) xor cc(VBIT)) = '1'); + when "1110" => -- bgt + cond_true := ((cc(ZBIT) or (cc(NBIT) xor cc(VBIT))) = '0'); + when "1111" => -- ble + cond_true := ((cc(ZBIT) or (cc(NBIT) xor cc(VBIT))) = '1'); + when others => + null; + end case; + end if; + if cond_true then + pc_ctrl <= load_pc; + end if; + lic <= '1'; + next_state <= fetch_state; + + -- + -- push return address onto the S stack + -- + -- (sp) = pc_lo + -- sp = sp - 1 + -- + when push_return_lo_state => + -- decrement the sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + sp_ctrl <= load_sp; + -- write PC low + addr_ctrl <= pushs_ad; + dout_ctrl <= pc_lo_dout; + next_state <= push_return_hi_state; + + -- + -- push program counter hi byte onto the stack + -- (sp) = pc_hi + -- sp = sp + -- return to originating state + -- + when push_return_hi_state => + -- write pc hi bytes + addr_ctrl <= pushs_ad; + dout_ctrl <= pc_hi_dout; + next_state <= saved_state; + + -- + -- RTS pull return address from stack + -- + when pull_return_hi_state => + -- increment the sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= load_sp; + -- read pc hi + pc_ctrl <= pull_hi_pc; + addr_ctrl <= pulls_ad; + next_state <= pull_return_lo_state; + + when pull_return_lo_state => + -- increment the SP + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= load_sp; + -- read pc low + pc_ctrl <= pull_lo_pc; + addr_ctrl <= pulls_ad; + dout_ctrl <= pc_lo_dout; + -- + lic <= '1'; + next_state <= fetch_state; + + when andcc_state => + -- AND CC with md + left_ctrl <= md_left; + right_ctrl <= zero_right; + alu_ctrl <= alu_andcc; + cc_ctrl <= load_cc; + -- + lic <= '1'; + next_state <= fetch_state; + + when orcc_state => + -- OR CC with md + left_ctrl <= md_left; + right_ctrl <= zero_right; + alu_ctrl <= alu_orcc; + cc_ctrl <= load_cc; + -- + lic <= '1'; + next_state <= fetch_state; + + when tfr_state => + -- select source register + case md(7 downto 4) is + when "0000" => + left_ctrl <= accd_left; + when "0001" => + left_ctrl <= ix_left; + when "0010" => + left_ctrl <= iy_left; + when "0011" => + left_ctrl <= up_left; + when "0100" => + left_ctrl <= sp_left; + when "0101" => + left_ctrl <= pc_left; + when "1000" => + left_ctrl <= acca_left; + when "1001" => + left_ctrl <= accb_left; + when "1010" => + left_ctrl <= cc_left; + when "1011" => + left_ctrl <= dp_left; + when others => + left_ctrl <= md_left; + end case; + right_ctrl <= zero_right; + alu_ctrl <= alu_tfr; + -- select destination register + case md(3 downto 0) is + when "0000" => -- accd + acca_ctrl <= load_hi_acca; + accb_ctrl <= load_accb; + when "0001" => -- ix + ix_ctrl <= load_ix; + when "0010" => -- iy + iy_ctrl <= load_iy; + when "0011" => -- up + up_ctrl <= load_up; + when "0100" => -- sp + sp_ctrl <= load_sp; + when "0101" => -- pc + pc_ctrl <= load_pc; + when "1000" => -- acca + acca_ctrl <= load_acca; + when "1001" => -- accb + accb_ctrl <= load_accb; + when "1010" => -- cc + cc_ctrl <= load_cc; + when "1011" => --dp + dp_ctrl <= load_dp; + when others => + null; + end case; + -- + lic <= '1'; + next_state <= fetch_state; + + when exg_state => + -- save destination register + case md(3 downto 0) is + when "0000" => + left_ctrl <= accd_left; + when "0001" => + left_ctrl <= ix_left; + when "0010" => + left_ctrl <= iy_left; + when "0011" => + left_ctrl <= up_left; + when "0100" => + left_ctrl <= sp_left; + when "0101" => + left_ctrl <= pc_left; + when "1000" => + left_ctrl <= acca_left; + when "1001" => + left_ctrl <= accb_left; + when "1010" => + left_ctrl <= cc_left; + when "1011" => + left_ctrl <= dp_left; + when others => + left_ctrl <= md_left; + end case; + right_ctrl <= zero_right; + alu_ctrl <= alu_tfr; + ea_ctrl <= load_ea; + -- call tranfer microcode + next_state <= exg1_state; + + when exg1_state => + -- select source register + case md(7 downto 4) is + when "0000" => + left_ctrl <= accd_left; + when "0001" => + left_ctrl <= ix_left; + when "0010" => + left_ctrl <= iy_left; + when "0011" => + left_ctrl <= up_left; + when "0100" => + left_ctrl <= sp_left; + when "0101" => + left_ctrl <= pc_left; + when "1000" => + left_ctrl <= acca_left; + when "1001" => + left_ctrl <= accb_left; + when "1010" => + left_ctrl <= cc_left; + when "1011" => + left_ctrl <= dp_left; + when others => + left_ctrl <= md_left; + end case; + right_ctrl <= zero_right; + alu_ctrl <= alu_tfr; + -- select destination register + case md(3 downto 0) is + when "0000" => -- accd + acca_ctrl <= load_hi_acca; + accb_ctrl <= load_accb; + when "0001" => -- ix + ix_ctrl <= load_ix; + when "0010" => -- iy + iy_ctrl <= load_iy; + when "0011" => -- up + up_ctrl <= load_up; + when "0100" => -- sp + sp_ctrl <= load_sp; + when "0101" => -- pc + pc_ctrl <= load_pc; + when "1000" => -- acca + acca_ctrl <= load_acca; + when "1001" => -- accb + accb_ctrl <= load_accb; + when "1010" => -- cc + cc_ctrl <= load_cc; + when "1011" => --dp + dp_ctrl <= load_dp; + when others => + null; + end case; + next_state <= exg2_state; + + when exg2_state => + -- restore destination + left_ctrl <= ea_left; + right_ctrl <= zero_right; + alu_ctrl <= alu_tfr; + -- save as source register + case md(7 downto 4) is + when "0000" => -- accd + acca_ctrl <= load_hi_acca; + accb_ctrl <= load_accb; + when "0001" => -- ix + ix_ctrl <= load_ix; + when "0010" => -- iy + iy_ctrl <= load_iy; + when "0011" => -- up + up_ctrl <= load_up; + when "0100" => -- sp + sp_ctrl <= load_sp; + when "0101" => -- pc + pc_ctrl <= load_pc; + when "1000" => -- acca + acca_ctrl <= load_acca; + when "1001" => -- accb + accb_ctrl <= load_accb; + when "1010" => -- cc + cc_ctrl <= load_cc; + when "1011" => --dp + dp_ctrl <= load_dp; + when others => + null; + end case; + lic <= '1'; + next_state <= fetch_state; + + when mul_state => + -- move acca to md + left_ctrl <= acca_left; + right_ctrl <= zero_right; + alu_ctrl <= alu_st16; + md_ctrl <= load_md; + next_state <= mulea_state; + + when mulea_state => + -- move accb to ea + left_ctrl <= accb_left; + right_ctrl <= zero_right; + alu_ctrl <= alu_st16; + ea_ctrl <= load_ea; + next_state <= muld_state; + + when muld_state => + -- clear accd + left_ctrl <= acca_left; + right_ctrl <= zero_right; + alu_ctrl <= alu_ld8; + acca_ctrl <= load_hi_acca; + accb_ctrl <= load_accb; + next_state <= mul0_state; + + when mul0_state => + -- if bit 0 of ea set, add accd to md + left_ctrl <= accd_left; + if ea(0) = '1' then + right_ctrl <= md_right; + else + right_ctrl <= zero_right; + end if; + alu_ctrl <= alu_mul; + cc_ctrl <= load_cc; + acca_ctrl <= load_hi_acca; + accb_ctrl <= load_accb; + md_ctrl <= shiftl_md; + next_state <= mul1_state; + + when mul1_state => + -- if bit 1 of ea set, add accd to md + left_ctrl <= accd_left; + if ea(1) = '1' then + right_ctrl <= md_right; + else + right_ctrl <= zero_right; + end if; + alu_ctrl <= alu_mul; + cc_ctrl <= load_cc; + acca_ctrl <= load_hi_acca; + accb_ctrl <= load_accb; + md_ctrl <= shiftl_md; + next_state <= mul2_state; + + when mul2_state => + -- if bit 2 of ea set, add accd to md + left_ctrl <= accd_left; + if ea(2) = '1' then + right_ctrl <= md_right; + else + right_ctrl <= zero_right; + end if; + alu_ctrl <= alu_mul; + cc_ctrl <= load_cc; + acca_ctrl <= load_hi_acca; + accb_ctrl <= load_accb; + md_ctrl <= shiftl_md; + next_state <= mul3_state; + + when mul3_state => + -- if bit 3 of ea set, add accd to md + left_ctrl <= accd_left; + if ea(3) = '1' then + right_ctrl <= md_right; + else + right_ctrl <= zero_right; + end if; + alu_ctrl <= alu_mul; + cc_ctrl <= load_cc; + acca_ctrl <= load_hi_acca; + accb_ctrl <= load_accb; + md_ctrl <= shiftl_md; + next_state <= mul4_state; + + when mul4_state => + -- if bit 4 of ea set, add accd to md + left_ctrl <= accd_left; + if ea(4) = '1' then + right_ctrl <= md_right; + else + right_ctrl <= zero_right; + end if; + alu_ctrl <= alu_mul; + cc_ctrl <= load_cc; + acca_ctrl <= load_hi_acca; + accb_ctrl <= load_accb; + md_ctrl <= shiftl_md; + next_state <= mul5_state; + + when mul5_state => + -- if bit 5 of ea set, add accd to md + left_ctrl <= accd_left; + if ea(5) = '1' then + right_ctrl <= md_right; + else + right_ctrl <= zero_right; + end if; + alu_ctrl <= alu_mul; + cc_ctrl <= load_cc; + acca_ctrl <= load_hi_acca; + accb_ctrl <= load_accb; + md_ctrl <= shiftl_md; + next_state <= mul6_state; + + when mul6_state => + -- if bit 6 of ea set, add accd to md + left_ctrl <= accd_left; + if ea(6) = '1' then + right_ctrl <= md_right; + else + right_ctrl <= zero_right; + end if; + alu_ctrl <= alu_mul; + cc_ctrl <= load_cc; + acca_ctrl <= load_hi_acca; + accb_ctrl <= load_accb; + md_ctrl <= shiftl_md; + next_state <= mul7_state; + + when mul7_state => + -- if bit 7 of ea set, add accd to md + left_ctrl <= accd_left; + if ea(7) = '1' then + right_ctrl <= md_right; + else + right_ctrl <= zero_right; + end if; + alu_ctrl <= alu_mul; + cc_ctrl <= load_cc; + acca_ctrl <= load_hi_acca; + accb_ctrl <= load_accb; + md_ctrl <= shiftl_md; + lic <= '1'; + next_state <= fetch_state; + + -- + -- Enter here on pushs + -- ea holds post byte + -- + when pshs_state => + -- decrement sp if any registers to be pushed + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + -- idle address + addr_ctrl <= idle_ad; + dout_ctrl <= cc_dout; + if ea(7 downto 0) = "00000000" then + sp_ctrl <= latch_sp; + else + sp_ctrl <= load_sp; + end if; + if ea(7) = '1' then + next_state <= pshs_pcl_state; + elsif ea(6) = '1' then + next_state <= pshs_upl_state; + elsif ea(5) = '1' then + next_state <= pshs_iyl_state; + elsif ea(4) = '1' then + next_state <= pshs_ixl_state; + elsif ea(3) = '1' then + next_state <= pshs_dp_state; + elsif ea(2) = '1' then + next_state <= pshs_accb_state; + elsif ea(1) = '1' then + next_state <= pshs_acca_state; + elsif ea(0) = '1' then + next_state <= pshs_cc_state; + else + lic <= '1'; + next_state <= fetch_state; + end if; + + when pshs_pcl_state => + -- decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + sp_ctrl <= load_sp; + -- write pc low + addr_ctrl <= pushs_ad; + dout_ctrl <= pc_lo_dout; + next_state <= pshs_pch_state; + + when pshs_pch_state => + -- decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + if ea(6 downto 0) = "0000000" then + sp_ctrl <= latch_sp; + else + sp_ctrl <= load_sp; + end if; + -- write pc hi + addr_ctrl <= pushs_ad; + dout_ctrl <= pc_hi_dout; + if ea(6) = '1' then + next_state <= pshs_upl_state; + elsif ea(5) = '1' then + next_state <= pshs_iyl_state; + elsif ea(4) = '1' then + next_state <= pshs_ixl_state; + elsif ea(3) = '1' then + next_state <= pshs_dp_state; + elsif ea(2) = '1' then + next_state <= pshs_accb_state; + elsif ea(1) = '1' then + next_state <= pshs_acca_state; + elsif ea(0) = '1' then + next_state <= pshs_cc_state; + else + lic <= '1'; + next_state <= fetch_state; + end if; + + + when pshs_upl_state => + -- decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + sp_ctrl <= load_sp; + -- write pc low + addr_ctrl <= pushs_ad; + dout_ctrl <= up_lo_dout; + next_state <= pshs_uph_state; + + when pshs_uph_state => + -- decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + if ea(5 downto 0) = "000000" then + sp_ctrl <= latch_sp; + else + sp_ctrl <= load_sp; + end if; + -- write pc hi + addr_ctrl <= pushs_ad; + dout_ctrl <= up_hi_dout; + if ea(5) = '1' then + next_state <= pshs_iyl_state; + elsif ea(4) = '1' then + next_state <= pshs_ixl_state; + elsif ea(3) = '1' then + next_state <= pshs_dp_state; + elsif ea(2) = '1' then + next_state <= pshs_accb_state; + elsif ea(1) = '1' then + next_state <= pshs_acca_state; + elsif ea(0) = '1' then + next_state <= pshs_cc_state; + else + lic <= '1'; + next_state <= fetch_state; + end if; + + when pshs_iyl_state => + -- decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + sp_ctrl <= load_sp; + -- write iy low + addr_ctrl <= pushs_ad; + dout_ctrl <= iy_lo_dout; + next_state <= pshs_iyh_state; + + when pshs_iyh_state => + -- decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + if ea(4 downto 0) = "00000" then + sp_ctrl <= latch_sp; + else + sp_ctrl <= load_sp; + end if; + -- write iy hi + addr_ctrl <= pushs_ad; + dout_ctrl <= iy_hi_dout; + if ea(4) = '1' then + next_state <= pshs_ixl_state; + elsif ea(3) = '1' then + next_state <= pshs_dp_state; + elsif ea(2) = '1' then + next_state <= pshs_accb_state; + elsif ea(1) = '1' then + next_state <= pshs_acca_state; + elsif ea(0) = '1' then + next_state <= pshs_cc_state; + else + lic <= '1'; + next_state <= fetch_state; + end if; + + when pshs_ixl_state => + -- decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + sp_ctrl <= load_sp; + -- write ix low + addr_ctrl <= pushs_ad; + dout_ctrl <= ix_lo_dout; + next_state <= pshs_ixh_state; + + when pshs_ixh_state => + -- decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + if ea(3 downto 0) = "0000" then + sp_ctrl <= latch_sp; + else + sp_ctrl <= load_sp; + end if; + -- write ix hi + addr_ctrl <= pushs_ad; + dout_ctrl <= ix_hi_dout; + if ea(3) = '1' then + next_state <= pshs_dp_state; + elsif ea(2) = '1' then + next_state <= pshs_accb_state; + elsif ea(1) = '1' then + next_state <= pshs_acca_state; + elsif ea(0) = '1' then + next_state <= pshs_cc_state; + else + lic <= '1'; + next_state <= fetch_state; + end if; + + when pshs_dp_state => + -- decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + if ea(2 downto 0) = "000" then + sp_ctrl <= latch_sp; + else + sp_ctrl <= load_sp; + end if; + -- write dp + addr_ctrl <= pushs_ad; + dout_ctrl <= dp_dout; + if ea(2) = '1' then + next_state <= pshs_accb_state; + elsif ea(1) = '1' then + next_state <= pshs_acca_state; + elsif ea(0) = '1' then + next_state <= pshs_cc_state; + else + lic <= '1'; + next_state <= fetch_state; + end if; + + when pshs_accb_state => + -- decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + if ea(1 downto 0) = "00" then + sp_ctrl <= latch_sp; + else + sp_ctrl <= load_sp; + end if; + -- write accb + addr_ctrl <= pushs_ad; + dout_ctrl <= accb_dout; + if ea(1) = '1' then + next_state <= pshs_acca_state; + elsif ea(0) = '1' then + next_state <= pshs_cc_state; + else + lic <= '1'; + next_state <= fetch_state; + end if; + + when pshs_acca_state => + -- decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + if ea(0) = '1' then + sp_ctrl <= load_sp; + else + sp_ctrl <= latch_sp; + end if; + -- write acca + addr_ctrl <= pushs_ad; + dout_ctrl <= acca_dout; + if ea(0) = '1' then + next_state <= pshs_cc_state; + else + lic <= '1'; + next_state <= fetch_state; + end if; + + when pshs_cc_state => + -- idle sp + -- write cc + addr_ctrl <= pushs_ad; + dout_ctrl <= cc_dout; + lic <= '1'; + next_state <= fetch_state; + + -- + -- enter here on PULS + -- ea hold register mask + -- + when puls_state => + if ea(0) = '1' then + next_state <= puls_cc_state; + elsif ea(1) = '1' then + next_state <= puls_acca_state; + elsif ea(2) = '1' then + next_state <= puls_accb_state; + elsif ea(3) = '1' then + next_state <= puls_dp_state; + elsif ea(4) = '1' then + next_state <= puls_ixh_state; + elsif ea(5) = '1' then + next_state <= puls_iyh_state; + elsif ea(6) = '1' then + next_state <= puls_uph_state; + elsif ea(7) = '1' then + next_state <= puls_pch_state; + else + lic <= '1'; + next_state <= fetch_state; + end if; + + when puls_cc_state => + -- increment sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= load_sp; + -- read cc + cc_ctrl <= pull_cc; + addr_ctrl <= pulls_ad; + if ea(1) = '1' then + next_state <= puls_acca_state; + elsif ea(2) = '1' then + next_state <= puls_accb_state; + elsif ea(3) = '1' then + next_state <= puls_dp_state; + elsif ea(4) = '1' then + next_state <= puls_ixh_state; + elsif ea(5) = '1' then + next_state <= puls_iyh_state; + elsif ea(6) = '1' then + next_state <= puls_uph_state; + elsif ea(7) = '1' then + next_state <= puls_pch_state; + else + lic <= '1'; + next_state <= fetch_state; + end if; + + when puls_acca_state => + -- increment sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= load_sp; + -- read acca + acca_ctrl <= pull_acca; + addr_ctrl <= pulls_ad; + if ea(2) = '1' then + next_state <= puls_accb_state; + elsif ea(3) = '1' then + next_state <= puls_dp_state; + elsif ea(4) = '1' then + next_state <= puls_ixh_state; + elsif ea(5) = '1' then + next_state <= puls_iyh_state; + elsif ea(6) = '1' then + next_state <= puls_uph_state; + elsif ea(7) = '1' then + next_state <= puls_pch_state; + else + lic <= '1'; + next_state <= fetch_state; + end if; + + when puls_accb_state => + -- increment sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= load_sp; + -- read accb + accb_ctrl <= pull_accb; + addr_ctrl <= pulls_ad; + if ea(3) = '1' then + next_state <= puls_dp_state; + elsif ea(4) = '1' then + next_state <= puls_ixh_state; + elsif ea(5) = '1' then + next_state <= puls_iyh_state; + elsif ea(6) = '1' then + next_state <= puls_uph_state; + elsif ea(7) = '1' then + next_state <= puls_pch_state; + else + lic <= '1'; + next_state <= fetch_state; + end if; + + when puls_dp_state => + -- increment sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= load_sp; + -- read dp + dp_ctrl <= pull_dp; + addr_ctrl <= pulls_ad; + if ea(4) = '1' then + next_state <= puls_ixh_state; + elsif ea(5) = '1' then + next_state <= puls_iyh_state; + elsif ea(6) = '1' then + next_state <= puls_uph_state; + elsif ea(7) = '1' then + next_state <= puls_pch_state; + else + lic <= '1'; + next_state <= fetch_state; + end if; + + when puls_ixh_state => + -- increment sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= load_sp; + -- pull ix hi + ix_ctrl <= pull_hi_ix; + addr_ctrl <= pulls_ad; + next_state <= puls_ixl_state; + + when puls_ixl_state => + -- increment sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= load_sp; + -- read ix low + ix_ctrl <= pull_lo_ix; + addr_ctrl <= pulls_ad; + if ea(5) = '1' then + next_state <= puls_iyh_state; + elsif ea(6) = '1' then + next_state <= puls_uph_state; + elsif ea(7) = '1' then + next_state <= puls_pch_state; + else + lic <= '1'; + next_state <= fetch_state; + end if; + + when puls_iyh_state => + -- increment sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= load_sp; + -- pull iy hi + iy_ctrl <= pull_hi_iy; + addr_ctrl <= pulls_ad; + next_state <= puls_iyl_state; + + when puls_iyl_state => + -- increment sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= load_sp; + -- read iy low + iy_ctrl <= pull_lo_iy; + addr_ctrl <= pulls_ad; + if ea(6) = '1' then + next_state <= puls_uph_state; + elsif ea(7) = '1' then + next_state <= puls_pch_state; + else + lic <= '1'; + next_state <= fetch_state; + end if; + + when puls_uph_state => + -- increment sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= load_sp; + -- pull up hi + up_ctrl <= pull_hi_up; + addr_ctrl <= pulls_ad; + next_state <= puls_upl_state; + + when puls_upl_state => + -- increment sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= load_sp; + -- read up low + up_ctrl <= pull_lo_up; + addr_ctrl <= pulls_ad; + if ea(7) = '1' then + next_state <= puls_pch_state; + else + lic <= '1'; + next_state <= fetch_state; + end if; + + when puls_pch_state => + -- increment sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= load_sp; + -- pull pc hi + pc_ctrl <= pull_hi_pc; + addr_ctrl <= pulls_ad; + next_state <= puls_pcl_state; + + when puls_pcl_state => + -- increment sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= load_sp; + -- read pc low + pc_ctrl <= pull_lo_pc; + addr_ctrl <= pulls_ad; + lic <= '1'; + next_state <= fetch_state; + + -- + -- Enter here on pshu + -- ea holds post byte + -- + when pshu_state => + -- decrement up if any registers to be pushed + left_ctrl <= up_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + if ea(7 downto 0) = "00000000" then + up_ctrl <= latch_up; + else + up_ctrl <= load_up; + end if; + -- write idle bus + if ea(7) = '1' then + next_state <= pshu_pcl_state; + elsif ea(6) = '1' then + next_state <= pshu_spl_state; + elsif ea(5) = '1' then + next_state <= pshu_iyl_state; + elsif ea(4) = '1' then + next_state <= pshu_ixl_state; + elsif ea(3) = '1' then + next_state <= pshu_dp_state; + elsif ea(2) = '1' then + next_state <= pshu_accb_state; + elsif ea(1) = '1' then + next_state <= pshu_acca_state; + elsif ea(0) = '1' then + next_state <= pshu_cc_state; + else + lic <= '1'; + next_state <= fetch_state; + end if; + -- + -- push PC onto U stack + -- + when pshu_pcl_state => + -- decrement up + left_ctrl <= up_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + up_ctrl <= load_up; + -- write pc low + addr_ctrl <= pushu_ad; + dout_ctrl <= pc_lo_dout; + next_state <= pshu_pch_state; + + when pshu_pch_state => + -- decrement up + left_ctrl <= up_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + if ea(6 downto 0) = "0000000" then + up_ctrl <= latch_up; + else + up_ctrl <= load_up; + end if; + -- write pc hi + addr_ctrl <= pushu_ad; + dout_ctrl <= pc_hi_dout; + if ea(6) = '1' then + next_state <= pshu_spl_state; + elsif ea(5) = '1' then + next_state <= pshu_iyl_state; + elsif ea(4) = '1' then + next_state <= pshu_ixl_state; + elsif ea(3) = '1' then + next_state <= pshu_dp_state; + elsif ea(2) = '1' then + next_state <= pshu_accb_state; + elsif ea(1) = '1' then + next_state <= pshu_acca_state; + elsif ea(0) = '1' then + next_state <= pshu_cc_state; + else + lic <= '1'; + next_state <= fetch_state; + end if; + + when pshu_spl_state => + -- decrement up + left_ctrl <= up_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + up_ctrl <= load_up; + -- write sp low + addr_ctrl <= pushu_ad; + dout_ctrl <= sp_lo_dout; + next_state <= pshu_sph_state; + + when pshu_sph_state => + -- decrement up + left_ctrl <= up_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + if ea(5 downto 0) = "000000" then + up_ctrl <= latch_up; + else + up_ctrl <= load_up; + end if; + -- write sp hi + addr_ctrl <= pushu_ad; + dout_ctrl <= sp_hi_dout; + if ea(5) = '1' then + next_state <= pshu_iyl_state; + elsif ea(4) = '1' then + next_state <= pshu_ixl_state; + elsif ea(3) = '1' then + next_state <= pshu_dp_state; + elsif ea(2) = '1' then + next_state <= pshu_accb_state; + elsif ea(1) = '1' then + next_state <= pshu_acca_state; + elsif ea(0) = '1' then + next_state <= pshu_cc_state; + else + lic <= '1'; + next_state <= fetch_state; + end if; + + when pshu_iyl_state => + -- decrement up + left_ctrl <= up_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + up_ctrl <= load_up; + -- write iy low + addr_ctrl <= pushu_ad; + dout_ctrl <= iy_lo_dout; + next_state <= pshu_iyh_state; + + when pshu_iyh_state => + -- decrement up + left_ctrl <= up_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + if ea(4 downto 0) = "00000" then + up_ctrl <= latch_up; + else + up_ctrl <= load_up; + end if; + -- write iy hi + addr_ctrl <= pushu_ad; + dout_ctrl <= iy_hi_dout; + if ea(4) = '1' then + next_state <= pshu_ixl_state; + elsif ea(3) = '1' then + next_state <= pshu_dp_state; + elsif ea(2) = '1' then + next_state <= pshu_accb_state; + elsif ea(1) = '1' then + next_state <= pshu_acca_state; + elsif ea(0) = '1' then + next_state <= pshu_cc_state; + else + lic <= '1'; + next_state <= fetch_state; + end if; + + when pshu_ixl_state => + -- decrement up + left_ctrl <= up_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + up_ctrl <= load_up; + -- write ix low + addr_ctrl <= pushu_ad; + dout_ctrl <= ix_lo_dout; + next_state <= pshu_ixh_state; + + when pshu_ixh_state => + -- decrement up + left_ctrl <= up_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + if ea(3 downto 0) = "0000" then + up_ctrl <= latch_up; + else + up_ctrl <= load_up; + end if; + -- write ix hi + addr_ctrl <= pushu_ad; + dout_ctrl <= ix_hi_dout; + if ea(3) = '1' then + next_state <= pshu_dp_state; + elsif ea(2) = '1' then + next_state <= pshu_accb_state; + elsif ea(1) = '1' then + next_state <= pshu_acca_state; + elsif ea(0) = '1' then + next_state <= pshu_cc_state; + else + lic <= '1'; + next_state <= fetch_state; + end if; + + when pshu_dp_state => + -- decrement up + left_ctrl <= up_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + if ea(2 downto 0) = "000" then + up_ctrl <= latch_up; + else + up_ctrl <= load_up; + end if; + -- write dp + addr_ctrl <= pushu_ad; + dout_ctrl <= dp_dout; + if ea(2) = '1' then + next_state <= pshu_accb_state; + elsif ea(1) = '1' then + next_state <= pshu_acca_state; + elsif ea(0) = '1' then + next_state <= pshu_cc_state; + else + lic <= '1'; + next_state <= fetch_state; + end if; + + when pshu_accb_state => + -- decrement up + left_ctrl <= up_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + if ea(1 downto 0) = "00" then + up_ctrl <= latch_up; + else + up_ctrl <= load_up; + end if; + -- write accb + addr_ctrl <= pushu_ad; + dout_ctrl <= accb_dout; + if ea(1) = '1' then + next_state <= pshu_acca_state; + elsif ea(0) = '1' then + next_state <= pshu_cc_state; + else + lic <= '1'; + next_state <= fetch_state; + end if; + + when pshu_acca_state => + -- decrement up + left_ctrl <= up_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + if ea(0) = '0' then + up_ctrl <= latch_up; + else + up_ctrl <= load_up; + end if; + -- write acca + addr_ctrl <= pushu_ad; + dout_ctrl <= acca_dout; + if ea(0) = '1' then + next_state <= pshu_cc_state; + else + lic <= '1'; + next_state <= fetch_state; + end if; + + when pshu_cc_state => + -- idle up + -- write cc + addr_ctrl <= pushu_ad; + dout_ctrl <= cc_dout; + lic <= '1'; + next_state <= fetch_state; + + -- + -- enter here on PULU + -- ea hold register mask + -- + when pulu_state => + -- idle UP + -- idle bus + if ea(0) = '1' then + next_state <= pulu_cc_state; + elsif ea(1) = '1' then + next_state <= pulu_acca_state; + elsif ea(2) = '1' then + next_state <= pulu_accb_state; + elsif ea(3) = '1' then + next_state <= pulu_dp_state; + elsif ea(4) = '1' then + next_state <= pulu_ixh_state; + elsif ea(5) = '1' then + next_state <= pulu_iyh_state; + elsif ea(6) = '1' then + next_state <= pulu_sph_state; + elsif ea(7) = '1' then + next_state <= pulu_pch_state; + else + lic <= '1'; + next_state <= fetch_state; + end if; + + when pulu_cc_state => + -- increment up + left_ctrl <= up_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + up_ctrl <= load_up; + -- read cc + cc_ctrl <= pull_cc; + addr_ctrl <= pullu_ad; + if ea(1) = '1' then + next_state <= pulu_acca_state; + elsif ea(2) = '1' then + next_state <= pulu_accb_state; + elsif ea(3) = '1' then + next_state <= pulu_dp_state; + elsif ea(4) = '1' then + next_state <= pulu_ixh_state; + elsif ea(5) = '1' then + next_state <= pulu_iyh_state; + elsif ea(6) = '1' then + next_state <= pulu_sph_state; + elsif ea(7) = '1' then + next_state <= pulu_pch_state; + else + lic <= '1'; + next_state <= fetch_state; + end if; + + when pulu_acca_state => + -- increment up + left_ctrl <= up_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + up_ctrl <= load_up; + -- read acca + acca_ctrl <= pull_acca; + addr_ctrl <= pullu_ad; + if ea(2) = '1' then + next_state <= pulu_accb_state; + elsif ea(3) = '1' then + next_state <= pulu_dp_state; + elsif ea(4) = '1' then + next_state <= pulu_ixh_state; + elsif ea(5) = '1' then + next_state <= pulu_iyh_state; + elsif ea(6) = '1' then + next_state <= pulu_sph_state; + elsif ea(7) = '1' then + next_state <= pulu_pch_state; + else + lic <= '1'; + next_state <= fetch_state; + end if; + + when pulu_accb_state => + -- increment up + left_ctrl <= up_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + up_ctrl <= load_up; + -- read accb + accb_ctrl <= pull_accb; + addr_ctrl <= pullu_ad; + if ea(3) = '1' then + next_state <= pulu_dp_state; + elsif ea(4) = '1' then + next_state <= pulu_ixh_state; + elsif ea(5) = '1' then + next_state <= pulu_iyh_state; + elsif ea(6) = '1' then + next_state <= pulu_sph_state; + elsif ea(7) = '1' then + next_state <= pulu_pch_state; + else + lic <= '1'; + next_state <= fetch_state; + end if; + + when pulu_dp_state => + -- increment up + left_ctrl <= up_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + up_ctrl <= load_up; + -- read dp + dp_ctrl <= pull_dp; + addr_ctrl <= pullu_ad; + if ea(4) = '1' then + next_state <= pulu_ixh_state; + elsif ea(5) = '1' then + next_state <= pulu_iyh_state; + elsif ea(6) = '1' then + next_state <= pulu_sph_state; + elsif ea(7) = '1' then + next_state <= pulu_pch_state; + else + lic <= '1'; + next_state <= fetch_state; + end if; + + when pulu_ixh_state => + -- increment up + left_ctrl <= up_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + up_ctrl <= load_up; + -- read ix hi + ix_ctrl <= pull_hi_ix; + addr_ctrl <= pullu_ad; + next_state <= pulu_ixl_state; + + when pulu_ixl_state => + -- increment up + left_ctrl <= up_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + up_ctrl <= load_up; + -- read ix low + ix_ctrl <= pull_lo_ix; + addr_ctrl <= pullu_ad; + if ea(5) = '1' then + next_state <= pulu_iyh_state; + elsif ea(6) = '1' then + next_state <= pulu_sph_state; + elsif ea(7) = '1' then + next_state <= pulu_pch_state; + else + lic <= '1'; + next_state <= fetch_state; + end if; + + when pulu_iyh_state => + -- increment up + left_ctrl <= up_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + up_ctrl <= load_up; + -- read iy hi + iy_ctrl <= pull_hi_iy; + addr_ctrl <= pullu_ad; + next_state <= pulu_iyl_state; + + when pulu_iyl_state => + -- increment up + left_ctrl <= up_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + up_ctrl <= load_up; + -- read iy low + iy_ctrl <= pull_lo_iy; + addr_ctrl <= pullu_ad; + if ea(6) = '1' then + next_state <= pulu_sph_state; + elsif ea(7) = '1' then + next_state <= pulu_pch_state; + else + lic <= '1'; + next_state <= fetch_state; + end if; + + when pulu_sph_state => + -- increment up + left_ctrl <= up_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + up_ctrl <= load_up; + -- read sp hi + sp_ctrl <= pull_hi_sp; + addr_ctrl <= pullu_ad; + next_state <= pulu_spl_state; + + when pulu_spl_state => + -- increment up + left_ctrl <= up_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + up_ctrl <= load_up; + -- read sp low + sp_ctrl <= pull_lo_sp; + addr_ctrl <= pullu_ad; + if ea(7) = '1' then + next_state <= pulu_pch_state; + else + lic <= '1'; + next_state <= fetch_state; + end if; + + when pulu_pch_state => + -- increment up + left_ctrl <= up_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + up_ctrl <= load_up; + -- pull pc hi + pc_ctrl <= pull_hi_pc; + addr_ctrl <= pullu_ad; + next_state <= pulu_pcl_state; + + when pulu_pcl_state => + -- increment up + left_ctrl <= up_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + up_ctrl <= load_up; + -- read pc low + pc_ctrl <= pull_lo_pc; + addr_ctrl <= pullu_ad; + lic <= '1'; + next_state <= fetch_state; + + -- + -- pop the Condition codes + -- + when rti_cc_state => + -- increment sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= load_sp; + -- read cc + cc_ctrl <= pull_cc; + addr_ctrl <= pulls_ad; + next_state <= rti_entire_state; + + -- + -- Added RTI cycle 11th July 2006 John Kent. + -- test the "Entire" Flag + -- that has just been popped off the stack + -- + when rti_entire_state => + -- + -- The Entire flag must be recovered from the stack + -- before testing. + -- + if cc(EBIT) = '1' then + next_state <= rti_acca_state; + else + next_state <= rti_pch_state; + end if; + + when rti_acca_state => + -- increment sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= load_sp; + -- read acca + acca_ctrl <= pull_acca; + addr_ctrl <= pulls_ad; + next_state <= rti_accb_state; + + when rti_accb_state => + -- increment sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= load_sp; + -- read accb + accb_ctrl <= pull_accb; + addr_ctrl <= pulls_ad; + next_state <= rti_dp_state; + + when rti_dp_state => + -- increment sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= load_sp; + -- read dp + dp_ctrl <= pull_dp; + addr_ctrl <= pulls_ad; + next_state <= rti_ixh_state; + + when rti_ixh_state => + -- increment sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= load_sp; + -- read ix hi + ix_ctrl <= pull_hi_ix; + addr_ctrl <= pulls_ad; + next_state <= rti_ixl_state; + + when rti_ixl_state => + -- increment sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= load_sp; + -- read ix low + ix_ctrl <= pull_lo_ix; + addr_ctrl <= pulls_ad; + next_state <= rti_iyh_state; + + when rti_iyh_state => + -- increment sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= load_sp; + -- read iy hi + iy_ctrl <= pull_hi_iy; + addr_ctrl <= pulls_ad; + next_state <= rti_iyl_state; + + when rti_iyl_state => + -- increment sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= load_sp; + -- read iy low + iy_ctrl <= pull_lo_iy; + addr_ctrl <= pulls_ad; + next_state <= rti_uph_state; + + + when rti_uph_state => + -- increment sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= load_sp; + -- read up hi + up_ctrl <= pull_hi_up; + addr_ctrl <= pulls_ad; + next_state <= rti_upl_state; + + when rti_upl_state => + -- increment sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= load_sp; + -- read up low + up_ctrl <= pull_lo_up; + addr_ctrl <= pulls_ad; + next_state <= rti_pch_state; + + when rti_pch_state => + -- increment sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= load_sp; + -- pull pc hi + pc_ctrl <= pull_hi_pc; + addr_ctrl <= pulls_ad; + next_state <= rti_pcl_state; + + when rti_pcl_state => + -- increment sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_add16; + sp_ctrl <= load_sp; + -- pull pc low + pc_ctrl <= pull_lo_pc; + addr_ctrl <= pulls_ad; + lic <= '1'; + next_state <= fetch_state; + + -- + -- here on NMI interrupt + -- Complete execute cycle of the last instruction. + -- If it was a dual operand instruction + -- + when int_nmi_state => + next_state <= int_nmi1_state; + + -- Idle bus cycle + when int_nmi1_state => + -- pre decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + sp_ctrl <= load_sp; + iv_ctrl <= nmi_iv; + st_ctrl <= push_st; + return_state <= int_nmimask_state; + next_state <= int_entire_state; + + -- + -- here on IRQ interrupt + -- Complete execute cycle of the last instruction. + -- If it was a dual operand instruction + -- + when int_irq_state => + next_state <= int_irq1_state; + + -- pre decrement the sp + -- Idle bus cycle + when int_irq1_state => + -- pre decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + sp_ctrl <= load_sp; + iv_ctrl <= irq_iv; + st_ctrl <= push_st; + return_state <= int_irqmask_state; + next_state <= int_entire_state; + + -- + -- here on FIRQ interrupt + -- Complete execution cycle of the last instruction + -- if it was a dual operand instruction + -- + when int_firq_state => + next_state <= int_firq1_state; + + -- Idle bus cycle + when int_firq1_state => + -- pre decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + sp_ctrl <= load_sp; + iv_ctrl <= firq_iv; + st_ctrl <= push_st; + return_state <= int_firqmask_state; + next_state <= int_fast_state; + + -- + -- CWAI entry point + -- stack pointer already pre-decremented + -- mask condition codes + -- + when cwai_state => + -- AND CC with md + left_ctrl <= md_left; + right_ctrl <= zero_right; + alu_ctrl <= alu_andcc; + cc_ctrl <= load_cc; + st_ctrl <= push_st; + return_state <= int_cwai_state; + next_state <= int_entire_state; + + -- + -- wait here for an interrupt + -- + when int_cwai_state => + if (nmi_req = '1') then + iv_ctrl <= nmi_iv; + next_state <= int_nmimask_state; + -- + -- FIRQ & IRQ are level sensitive + -- + elsif (firq = '1') and (cc(FBIT) = '0') then + iv_ctrl <= firq_iv; + next_state <= int_firqmask_state; + + elsif (irq = '1') and (cc(IBIT) = '0') then + iv_ctrl <= irq_iv; + next_state <= int_irqmask_state; + else + next_state <= int_cwai_state; + end if; + + -- + -- State to mask I Flag and F Flag (NMI) + -- + when int_nmimask_state => + alu_ctrl <= alu_seif; + cc_ctrl <= load_cc; + next_state <= vect_hi_state; + + -- + -- State to mask I Flag and F Flag (FIRQ) + -- + when int_firqmask_state => + alu_ctrl <= alu_seif; + cc_ctrl <= load_cc; + next_state <= vect_hi_state; + + + -- + -- State to mask I Flag and F Flag (SWI) + -- + when int_swimask_state => + alu_ctrl <= alu_seif; + cc_ctrl <= load_cc; + next_state <= vect_hi_state; + + -- + -- State to mask I Flag only (IRQ) + -- + when int_irqmask_state => + alu_ctrl <= alu_sei; + cc_ctrl <= load_cc; + next_state <= vect_hi_state; + + -- + -- set Entire Flag on SWI, SWI2, SWI3 and CWAI, IRQ and NMI + -- before stacking all registers + -- + when int_entire_state => + -- set entire flag + alu_ctrl <= alu_see; + cc_ctrl <= load_cc; + next_state <= int_pcl_state; + + -- + -- clear Entire Flag on FIRQ + -- before stacking all registers + -- + when int_fast_state => + -- clear entire flag + alu_ctrl <= alu_cle; + cc_ctrl <= load_cc; + next_state <= int_pcl_state; + + when int_pcl_state => + -- decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + sp_ctrl <= load_sp; + -- write pc low + addr_ctrl <= pushs_ad; + dout_ctrl <= pc_lo_dout; + next_state <= int_pch_state; + + when int_pch_state => + -- decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + sp_ctrl <= load_sp; + -- write pc hi + addr_ctrl <= pushs_ad; + dout_ctrl <= pc_hi_dout; + if cc(EBIT) = '1' then + next_state <= int_upl_state; + else + next_state <= int_cc_state; + end if; + + when int_upl_state => + -- decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + sp_ctrl <= load_sp; + -- write up low + addr_ctrl <= pushs_ad; + dout_ctrl <= up_lo_dout; + next_state <= int_uph_state; + + when int_uph_state => + -- decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + sp_ctrl <= load_sp; + -- write ix hi + addr_ctrl <= pushs_ad; + dout_ctrl <= up_hi_dout; + next_state <= int_iyl_state; + + when int_iyl_state => + -- decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + sp_ctrl <= load_sp; + -- write ix low + addr_ctrl <= pushs_ad; + dout_ctrl <= iy_lo_dout; + next_state <= int_iyh_state; + + when int_iyh_state => + -- decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + sp_ctrl <= load_sp; + -- write ix hi + addr_ctrl <= pushs_ad; + dout_ctrl <= iy_hi_dout; + next_state <= int_ixl_state; + + when int_ixl_state => + -- decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + sp_ctrl <= load_sp; + -- write ix low + addr_ctrl <= pushs_ad; + dout_ctrl <= ix_lo_dout; + next_state <= int_ixh_state; + + when int_ixh_state => + -- decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + sp_ctrl <= load_sp; + -- write ix hi + addr_ctrl <= pushs_ad; + dout_ctrl <= ix_hi_dout; + next_state <= int_dp_state; + + when int_dp_state => + -- decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + sp_ctrl <= load_sp; + -- write accb + addr_ctrl <= pushs_ad; + dout_ctrl <= dp_dout; + next_state <= int_accb_state; + + when int_accb_state => + -- decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + sp_ctrl <= load_sp; + -- write accb + addr_ctrl <= pushs_ad; + dout_ctrl <= accb_dout; + next_state <= int_acca_state; + + when int_acca_state => + -- decrement sp + left_ctrl <= sp_left; + right_ctrl <= one_right; + alu_ctrl <= alu_sub16; + sp_ctrl <= load_sp; + -- write acca + addr_ctrl <= pushs_ad; + dout_ctrl <= acca_dout; + next_state <= int_cc_state; + + when int_cc_state => + -- write cc + addr_ctrl <= pushs_ad; + dout_ctrl <= cc_dout; + next_state <= saved_state; + + -- + -- According to the 6809 programming manual: + -- If an interrupt is received and is masked + -- or lasts for less than three cycles, the PC + -- will advance to the next instruction. + -- If an interrupt is unmasked and lasts + -- for more than three cycles, an interrupt + -- will be generated. + -- Note that I don't wait 3 clock cycles. + -- John Kent 11th July 2006 + -- + when sync_state => + lic <= '1'; + ba <= '1'; + -- + -- Version 1.28 2015-05-30 + -- Exit sync_state on interrupt. + -- If the interrupts are active + -- they will be caught in the state_machine process + -- and the interrupt service routine microcode will be executed. + -- Masked interrupts will exit the sync_state. + -- Moved from the state_machine process to the state_sequencer process + -- + if (firq = '1') or (irq = '1') then + next_state <= fetch_state; + else + next_state <= sync_state; + end if; + + when halt_state => + -- + -- 2011-10-30 John Kent + -- ba & bs should be high + ba <= '1'; + bs <= '1'; + if halt = '1' then + next_state <= halt_state; + else + next_state <= fetch_state; + end if; + + end case; + +-- +-- Ver 1.23 2011-10-30 John Kent +-- First instruction cycle might be +-- fetch_state +-- halt_state +-- int_nmirq_state +-- int_firq_state +-- + if fic = '1' then + -- + case op_code(7 downto 6) is + when "10" => -- acca + case op_code(3 downto 0) is + when "0000" => -- suba + left_ctrl <= acca_left; + right_ctrl <= md_right; + alu_ctrl <= alu_sub8; + cc_ctrl <= load_cc; + acca_ctrl <= load_acca; + when "0001" => -- cmpa + left_ctrl <= acca_left; + right_ctrl <= md_right; + alu_ctrl <= alu_sub8; + cc_ctrl <= load_cc; + when "0010" => -- sbca + left_ctrl <= acca_left; + right_ctrl <= md_right; + alu_ctrl <= alu_sbc; + cc_ctrl <= load_cc; + acca_ctrl <= load_acca; + when "0011" => + case pre_code is + when "00010000" => -- page 2 -- cmpd + left_ctrl <= accd_left; + right_ctrl <= md_right; + alu_ctrl <= alu_sub16; + cc_ctrl <= load_cc; + when "00010001" => -- page 3 -- cmpu + left_ctrl <= up_left; + right_ctrl <= md_right; + alu_ctrl <= alu_sub16; + cc_ctrl <= load_cc; + when others => -- page 1 -- subd + left_ctrl <= accd_left; + right_ctrl <= md_right; + alu_ctrl <= alu_sub16; + cc_ctrl <= load_cc; + acca_ctrl <= load_hi_acca; + accb_ctrl <= load_accb; + end case; + when "0100" => -- anda + left_ctrl <= acca_left; + right_ctrl <= md_right; + alu_ctrl <= alu_and; + cc_ctrl <= load_cc; + acca_ctrl <= load_acca; + when "0101" => -- bita + left_ctrl <= acca_left; + right_ctrl <= md_right; + alu_ctrl <= alu_and; + cc_ctrl <= load_cc; + when "0110" => -- ldaa + left_ctrl <= acca_left; + right_ctrl <= md_right; + alu_ctrl <= alu_ld8; + cc_ctrl <= load_cc; + acca_ctrl <= load_acca; + when "0111" => -- staa + left_ctrl <= acca_left; + right_ctrl <= md_right; + alu_ctrl <= alu_st8; + cc_ctrl <= load_cc; + when "1000" => -- eora + left_ctrl <= acca_left; + right_ctrl <= md_right; + alu_ctrl <= alu_eor; + cc_ctrl <= load_cc; + acca_ctrl <= load_acca; + when "1001" => -- adca + left_ctrl <= acca_left; + right_ctrl <= md_right; + alu_ctrl <= alu_adc; + cc_ctrl <= load_cc; + acca_ctrl <= load_acca; + when "1010" => -- oraa + left_ctrl <= acca_left; + right_ctrl <= md_right; + alu_ctrl <= alu_ora; + cc_ctrl <= load_cc; + acca_ctrl <= load_acca; + when "1011" => -- adda + left_ctrl <= acca_left; + right_ctrl <= md_right; + alu_ctrl <= alu_add8; + cc_ctrl <= load_cc; + acca_ctrl <= load_acca; + when "1100" => + case pre_code is + when "00010000" => -- page 2 -- cmpy + left_ctrl <= iy_left; + right_ctrl <= md_right; + alu_ctrl <= alu_sub16; + cc_ctrl <= load_cc; + when "00010001" => -- page 3 -- cmps + left_ctrl <= sp_left; + right_ctrl <= md_right; + alu_ctrl <= alu_sub16; + cc_ctrl <= load_cc; + when others => -- page 1 -- cmpx + left_ctrl <= ix_left; + right_ctrl <= md_right; + alu_ctrl <= alu_sub16; + cc_ctrl <= load_cc; + end case; + when "1101" => -- bsr / jsr + null; + when "1110" => -- ldx + case pre_code is + when "00010000" => -- page 2 -- ldy + left_ctrl <= iy_left; + right_ctrl <= md_right; + alu_ctrl <= alu_ld16; + cc_ctrl <= load_cc; + iy_ctrl <= load_iy; + when others => -- page 1 -- ldx + left_ctrl <= ix_left; + right_ctrl <= md_right; + alu_ctrl <= alu_ld16; + cc_ctrl <= load_cc; + ix_ctrl <= load_ix; + end case; + when "1111" => -- stx + case pre_code is + when "00010000" => -- page 2 -- sty + left_ctrl <= iy_left; + right_ctrl <= md_right; + alu_ctrl <= alu_st16; + cc_ctrl <= load_cc; + when others => -- page 1 -- stx + left_ctrl <= ix_left; + right_ctrl <= md_right; + alu_ctrl <= alu_st16; + cc_ctrl <= load_cc; + end case; + when others => + null; + end case; + when "11" => -- accb dual op + case op_code(3 downto 0) is + when "0000" => -- subb + left_ctrl <= accb_left; + right_ctrl <= md_right; + alu_ctrl <= alu_sub8; + cc_ctrl <= load_cc; + accb_ctrl <= load_accb; + when "0001" => -- cmpb + left_ctrl <= accb_left; + right_ctrl <= md_right; + alu_ctrl <= alu_sub8; + cc_ctrl <= load_cc; + when "0010" => -- sbcb + left_ctrl <= accb_left; + right_ctrl <= md_right; + alu_ctrl <= alu_sbc; + cc_ctrl <= load_cc; + accb_ctrl <= load_accb; + when "0011" => -- addd + left_ctrl <= accd_left; + right_ctrl <= md_right; + alu_ctrl <= alu_add16; + cc_ctrl <= load_cc; + acca_ctrl <= load_hi_acca; + accb_ctrl <= load_accb; + when "0100" => -- andb + left_ctrl <= accb_left; + right_ctrl <= md_right; + alu_ctrl <= alu_and; + cc_ctrl <= load_cc; + accb_ctrl <= load_accb; + when "0101" => -- bitb + left_ctrl <= accb_left; + right_ctrl <= md_right; + alu_ctrl <= alu_and; + cc_ctrl <= load_cc; + when "0110" => -- ldab + left_ctrl <= accb_left; + right_ctrl <= md_right; + alu_ctrl <= alu_ld8; + cc_ctrl <= load_cc; + accb_ctrl <= load_accb; + when "0111" => -- stab + left_ctrl <= accb_left; + right_ctrl <= md_right; + alu_ctrl <= alu_st8; + cc_ctrl <= load_cc; + when "1000" => -- eorb + left_ctrl <= accb_left; + right_ctrl <= md_right; + alu_ctrl <= alu_eor; + cc_ctrl <= load_cc; + accb_ctrl <= load_accb; + when "1001" => -- adcb + left_ctrl <= accb_left; + right_ctrl <= md_right; + alu_ctrl <= alu_adc; + cc_ctrl <= load_cc; + accb_ctrl <= load_accb; + when "1010" => -- orab + left_ctrl <= accb_left; + right_ctrl <= md_right; + alu_ctrl <= alu_ora; + cc_ctrl <= load_cc; + accb_ctrl <= load_accb; + when "1011" => -- addb + left_ctrl <= accb_left; + right_ctrl <= md_right; + alu_ctrl <= alu_add8; + cc_ctrl <= load_cc; + accb_ctrl <= load_accb; + when "1100" => -- ldd + left_ctrl <= accd_left; + right_ctrl <= md_right; + alu_ctrl <= alu_ld16; + cc_ctrl <= load_cc; + acca_ctrl <= load_hi_acca; + accb_ctrl <= load_accb; + when "1101" => -- std + left_ctrl <= accd_left; + right_ctrl <= md_right; + alu_ctrl <= alu_st16; + cc_ctrl <= load_cc; + when "1110" => -- ldu + case pre_code is + when "00010000" => -- page 2 -- lds + left_ctrl <= sp_left; + right_ctrl <= md_right; + alu_ctrl <= alu_ld16; + cc_ctrl <= load_cc; + sp_ctrl <= load_sp; + when others => -- page 1 -- ldu + left_ctrl <= up_left; + right_ctrl <= md_right; + alu_ctrl <= alu_ld16; + cc_ctrl <= load_cc; + up_ctrl <= load_up; + end case; + when "1111" => + case pre_code is + when "00010000" => -- page 2 -- sts + left_ctrl <= sp_left; + right_ctrl <= md_right; + alu_ctrl <= alu_st16; + cc_ctrl <= load_cc; + when others => -- page 1 -- stu + left_ctrl <= up_left; + right_ctrl <= md_right; + alu_ctrl <= alu_st16; + cc_ctrl <= load_cc; + end case; + when others => + null; + end case; + when others => + null; + end case; + + end if; -- first instruction cycle (fic) + lic_out <= lic; +end process; + +end rtl; + diff --git a/GCE - Vectrex_MiST/rtl/dac.vhd b/GCE - Vectrex_MiST/rtl/dac.vhd new file mode 100644 index 00000000..83d1861e --- /dev/null +++ b/GCE - Vectrex_MiST/rtl/dac.vhd @@ -0,0 +1,71 @@ +------------------------------------------------------------------------------- +-- +-- Delta-Sigma DAC +-- +-- $Id: dac.vhd,v 1.1 2005/10/25 21:09:42 arnim Exp $ +-- +-- Refer to Xilinx Application Note XAPP154. +-- +-- This DAC requires an external RC low-pass filter: +-- +-- dac_o 0---XXXXX---+---0 analog audio +-- 3k3 | +-- === 4n7 +-- | +-- GND +-- +------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; + +entity dac is + + generic ( + msbi_g : integer := 9 + ); + port ( + clk_i : in std_logic; + res_n_i : in std_logic; + dac_i : in std_logic_vector(msbi_g downto 0); + dac_o : out std_logic + ); + +end dac; + +library ieee; +use ieee.numeric_std.all; + +architecture rtl of dac is + + signal DACout_q : std_logic; + signal DeltaAdder_s, + SigmaAdder_s, + SigmaLatch_q, + DeltaB_s : unsigned(msbi_g+2 downto 0); + +begin + + DeltaB_s(msbi_g+2 downto msbi_g+1) <= SigmaLatch_q(msbi_g+2) & + SigmaLatch_q(msbi_g+2); + DeltaB_s(msbi_g downto 0) <= (others => '0'); + + DeltaAdder_s <= unsigned('0' & '0' & dac_i) + DeltaB_s; + + SigmaAdder_s <= DeltaAdder_s + SigmaLatch_q; + + seq: process (clk_i, res_n_i) + begin + if res_n_i = '0' then + SigmaLatch_q <= to_unsigned(2**(msbi_g+1), SigmaLatch_q'length); + DACout_q <= '0'; + + elsif clk_i'event and clk_i = '1' then + SigmaLatch_q <= SigmaAdder_s; + DACout_q <= SigmaLatch_q(msbi_g+2); + end if; + end process seq; + + dac_o <= DACout_q; + +end rtl; diff --git a/GCE - Vectrex_MiST/rtl/gen_ram.vhd b/GCE - Vectrex_MiST/rtl/gen_ram.vhd new file mode 100644 index 00000000..f1a95608 --- /dev/null +++ b/GCE - Vectrex_MiST/rtl/gen_ram.vhd @@ -0,0 +1,84 @@ +-- ----------------------------------------------------------------------- +-- +-- Syntiac's generic VHDL support files. +-- +-- ----------------------------------------------------------------------- +-- Copyright 2005-2008 by Peter Wendrich (pwsoft@syntiac.com) +-- http://www.syntiac.com/fpga64.html +-- +-- Modified April 2016 by Dar (darfpga@aol.fr) +-- http://darfpga.blogspot.fr +-- Remove address register when writing +-- +-- ----------------------------------------------------------------------- +-- +-- gen_rwram.vhd +-- +-- ----------------------------------------------------------------------- +-- +-- generic ram. +-- +-- ----------------------------------------------------------------------- + +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.numeric_std.ALL; + +-- ----------------------------------------------------------------------- + +entity gen_ram is + generic ( + dWidth : integer := 8; + aWidth : integer := 10 + ); + port ( + clk : in std_logic; + we : in std_logic; + addr : in std_logic_vector((aWidth-1) downto 0); + d : in std_logic_vector((dWidth-1) downto 0); + q : out std_logic_vector((dWidth-1) downto 0) + ); +end entity; + +-- ----------------------------------------------------------------------- + +architecture rtl of gen_ram is + subtype addressRange is integer range 0 to ((2**aWidth)-1); + type ramDef is array(addressRange) of std_logic_vector((dWidth-1) downto 0); + signal ram: ramDef; + + signal rAddrReg : std_logic_vector((aWidth-1) downto 0); + signal qReg : std_logic_vector((dWidth-1) downto 0); +begin +-- ----------------------------------------------------------------------- +-- Signals to entity interface +-- ----------------------------------------------------------------------- +-- q <= qReg; + +-- ----------------------------------------------------------------------- +-- Memory write +-- ----------------------------------------------------------------------- + process(clk) + begin + if rising_edge(clk) then + if we = '1' then + ram(to_integer(unsigned(addr))) <= d; + end if; + end if; + end process; + +-- ----------------------------------------------------------------------- +-- Memory read +-- ----------------------------------------------------------------------- +process(clk) + begin + if rising_edge(clk) then +-- qReg <= ram(to_integer(unsigned(rAddrReg))); +-- rAddrReg <= addr; +---- qReg <= ram(to_integer(unsigned(addr))); + q <= ram(to_integer(unsigned(addr))); + end if; + end process; +--q <= ram(to_integer(unsigned(addr))); +end architecture; + diff --git a/GCE - Vectrex_MiST/rtl/hq2x.sv b/GCE - Vectrex_MiST/rtl/hq2x.sv new file mode 100644 index 00000000..f17732b6 --- /dev/null +++ b/GCE - Vectrex_MiST/rtl/hq2x.sv @@ -0,0 +1,454 @@ +// +// +// Copyright (c) 2012-2013 Ludvig Strigeus +// Copyright (c) 2017 Sorgelig +// +// This program is GPL Licensed. See COPYING for the full license. +// +// +//////////////////////////////////////////////////////////////////////////////////////////////////////// + +// synopsys translate_off +`timescale 1 ps / 1 ps +// synopsys translate_on + +`define BITS_TO_FIT(N) ( \ + N <= 2 ? 0 : \ + N <= 4 ? 1 : \ + N <= 8 ? 2 : \ + N <= 16 ? 3 : \ + N <= 32 ? 4 : \ + N <= 64 ? 5 : \ + N <= 128 ? 6 : \ + N <= 256 ? 7 : \ + N <= 512 ? 8 : \ + N <=1024 ? 9 : 10 ) + +module hq2x_in #(parameter LENGTH, parameter DWIDTH) +( + input clk, + + input [AWIDTH:0] rdaddr, + input rdbuf, + output[DWIDTH:0] q, + + input [AWIDTH:0] wraddr, + input wrbuf, + input [DWIDTH:0] data, + input wren +); + + localparam AWIDTH = `BITS_TO_FIT(LENGTH); + wire [DWIDTH:0] out[2]; + assign q = out[rdbuf]; + + hq2x_buf #(.NUMWORDS(LENGTH), .AWIDTH(AWIDTH), .DWIDTH(DWIDTH)) buf0(clk,data,rdaddr,wraddr,wren && (wrbuf == 0),out[0]); + hq2x_buf #(.NUMWORDS(LENGTH), .AWIDTH(AWIDTH), .DWIDTH(DWIDTH)) buf1(clk,data,rdaddr,wraddr,wren && (wrbuf == 1),out[1]); +endmodule + + +module hq2x_out #(parameter LENGTH, parameter DWIDTH) +( + input clk, + + input [AWIDTH:0] rdaddr, + input [1:0] rdbuf, + output[DWIDTH:0] q, + + input [AWIDTH:0] wraddr, + input [1:0] wrbuf, + input [DWIDTH:0] data, + input wren +); + + localparam AWIDTH = `BITS_TO_FIT(LENGTH*2); + wire [DWIDTH:0] out[4]; + assign q = out[rdbuf]; + + hq2x_buf #(.NUMWORDS(LENGTH*2), .AWIDTH(AWIDTH), .DWIDTH(DWIDTH)) buf0(clk,data,rdaddr,wraddr,wren && (wrbuf == 0),out[0]); + hq2x_buf #(.NUMWORDS(LENGTH*2), .AWIDTH(AWIDTH), .DWIDTH(DWIDTH)) buf1(clk,data,rdaddr,wraddr,wren && (wrbuf == 1),out[1]); + hq2x_buf #(.NUMWORDS(LENGTH*2), .AWIDTH(AWIDTH), .DWIDTH(DWIDTH)) buf2(clk,data,rdaddr,wraddr,wren && (wrbuf == 2),out[2]); + hq2x_buf #(.NUMWORDS(LENGTH*2), .AWIDTH(AWIDTH), .DWIDTH(DWIDTH)) buf3(clk,data,rdaddr,wraddr,wren && (wrbuf == 3),out[3]); +endmodule + + +module hq2x_buf #(parameter NUMWORDS, parameter AWIDTH, parameter DWIDTH) +( + input clock, + input [DWIDTH:0] data, + input [AWIDTH:0] rdaddress, + input [AWIDTH:0] wraddress, + input wren, + output [DWIDTH:0] q +); + + altsyncram altsyncram_component ( + .address_a (wraddress), + .clock0 (clock), + .data_a (data), + .wren_a (wren), + .address_b (rdaddress), + .q_b(q), + .aclr0 (1'b0), + .aclr1 (1'b0), + .addressstall_a (1'b0), + .addressstall_b (1'b0), + .byteena_a (1'b1), + .byteena_b (1'b1), + .clock1 (1'b1), + .clocken0 (1'b1), + .clocken1 (1'b1), + .clocken2 (1'b1), + .clocken3 (1'b1), + .data_b ({(DWIDTH+1){1'b1}}), + .eccstatus (), + .q_a (), + .rden_a (1'b1), + .rden_b (1'b1), + .wren_b (1'b0)); + defparam + altsyncram_component.address_aclr_b = "NONE", + altsyncram_component.address_reg_b = "CLOCK0", + altsyncram_component.clock_enable_input_a = "BYPASS", + altsyncram_component.clock_enable_input_b = "BYPASS", + altsyncram_component.clock_enable_output_b = "BYPASS", + altsyncram_component.intended_device_family = "Cyclone III", + altsyncram_component.lpm_type = "altsyncram", + altsyncram_component.numwords_a = NUMWORDS, + altsyncram_component.numwords_b = NUMWORDS, + altsyncram_component.operation_mode = "DUAL_PORT", + altsyncram_component.outdata_aclr_b = "NONE", + altsyncram_component.outdata_reg_b = "UNREGISTERED", + altsyncram_component.power_up_uninitialized = "FALSE", + altsyncram_component.read_during_write_mode_mixed_ports = "DONT_CARE", + altsyncram_component.widthad_a = AWIDTH+1, + altsyncram_component.widthad_b = AWIDTH+1, + altsyncram_component.width_a = DWIDTH+1, + altsyncram_component.width_b = DWIDTH+1, + altsyncram_component.width_byteena_a = 1; + +endmodule + +//////////////////////////////////////////////////////////////////////////////////////////////////////// + +module DiffCheck +( + input [17:0] rgb1, + input [17:0] rgb2, + output result +); + + wire [5:0] r = rgb1[5:1] - rgb2[5:1]; + wire [5:0] g = rgb1[11:7] - rgb2[11:7]; + wire [5:0] b = rgb1[17:13] - rgb2[17:13]; + wire [6:0] t = $signed(r) + $signed(b); + wire [6:0] gx = {g[5], g}; + wire [7:0] y = $signed(t) + $signed(gx); + wire [6:0] u = $signed(r) - $signed(b); + wire [7:0] v = $signed({g, 1'b0}) - $signed(t); + + // if y is inside (-24..24) + wire y_inside = (y < 8'h18 || y >= 8'he8); + + // if u is inside (-4, 4) + wire u_inside = (u < 7'h4 || u >= 7'h7c); + + // if v is inside (-6, 6) + wire v_inside = (v < 8'h6 || v >= 8'hfA); + assign result = !(y_inside && u_inside && v_inside); +endmodule + +module InnerBlend +( + input [8:0] Op, + input [5:0] A, + input [5:0] B, + input [5:0] C, + output [5:0] O +); + + function [8:0] mul6x3; + input [5:0] op1; + input [2:0] op2; + begin + mul6x3 = 9'd0; + if(op2[0]) mul6x3 = mul6x3 + op1; + if(op2[1]) mul6x3 = mul6x3 + {op1, 1'b0}; + if(op2[2]) mul6x3 = mul6x3 + {op1, 2'b00}; + end + endfunction + + wire OpOnes = Op[4]; + wire [8:0] Amul = mul6x3(A, Op[7:5]); + wire [8:0] Bmul = mul6x3(B, {Op[3:2], 1'b0}); + wire [8:0] Cmul = mul6x3(C, {Op[1:0], 1'b0}); + wire [8:0] At = Amul; + wire [8:0] Bt = (OpOnes == 0) ? Bmul : {3'b0, B}; + wire [8:0] Ct = (OpOnes == 0) ? Cmul : {3'b0, C}; + wire [9:0] Res = {At, 1'b0} + Bt + Ct; + assign O = Op[8] ? A : Res[9:4]; +endmodule + +module Blend +( + input [5:0] rule, + input disable_hq2x, + input [17:0] E, + input [17:0] A, + input [17:0] B, + input [17:0] D, + input [17:0] F, + input [17:0] H, + output [17:0] Result +); + + reg [1:0] input_ctrl; + reg [8:0] op; + localparam BLEND0 = 9'b1_xxx_x_xx_xx; // 0: A + localparam BLEND1 = 9'b0_110_0_10_00; // 1: (A * 12 + B * 4) >> 4 + localparam BLEND2 = 9'b0_100_0_10_10; // 2: (A * 8 + B * 4 + C * 4) >> 4 + localparam BLEND3 = 9'b0_101_0_10_01; // 3: (A * 10 + B * 4 + C * 2) >> 4 + localparam BLEND4 = 9'b0_110_0_01_01; // 4: (A * 12 + B * 2 + C * 2) >> 4 + localparam BLEND5 = 9'b0_010_0_11_11; // 5: (A * 4 + (B + C) * 6) >> 4 + localparam BLEND6 = 9'b0_111_1_xx_xx; // 6: (A * 14 + B + C) >> 4 + localparam AB = 2'b00; + localparam AD = 2'b01; + localparam DB = 2'b10; + localparam BD = 2'b11; + wire is_diff; + DiffCheck diff_checker(rule[1] ? B : H, rule[0] ? D : F, is_diff); + + always @* begin + case({!is_diff, rule[5:2]}) + 1,17: {op, input_ctrl} = {BLEND1, AB}; + 2,18: {op, input_ctrl} = {BLEND1, DB}; + 3,19: {op, input_ctrl} = {BLEND1, BD}; + 4,20: {op, input_ctrl} = {BLEND2, DB}; + 5,21: {op, input_ctrl} = {BLEND2, AB}; + 6,22: {op, input_ctrl} = {BLEND2, AD}; + + 8: {op, input_ctrl} = {BLEND0, 2'bxx}; + 9: {op, input_ctrl} = {BLEND0, 2'bxx}; + 10: {op, input_ctrl} = {BLEND0, 2'bxx}; + 11: {op, input_ctrl} = {BLEND1, AB}; + 12: {op, input_ctrl} = {BLEND1, AB}; + 13: {op, input_ctrl} = {BLEND1, AB}; + 14: {op, input_ctrl} = {BLEND1, DB}; + 15: {op, input_ctrl} = {BLEND1, BD}; + + 24: {op, input_ctrl} = {BLEND2, DB}; + 25: {op, input_ctrl} = {BLEND5, DB}; + 26: {op, input_ctrl} = {BLEND6, DB}; + 27: {op, input_ctrl} = {BLEND2, DB}; + 28: {op, input_ctrl} = {BLEND4, DB}; + 29: {op, input_ctrl} = {BLEND5, DB}; + 30: {op, input_ctrl} = {BLEND3, BD}; + 31: {op, input_ctrl} = {BLEND3, DB}; + default: {op, input_ctrl} = 11'bx; + endcase + + // Setting op[8] effectively disables HQ2X because blend will always return E. + if (disable_hq2x) op[8] = 1; + end + + // Generate inputs to the inner blender. Valid combinations. + // 00: E A B + // 01: E A D + // 10: E D B + // 11: E B D + wire [17:0] Input1 = E; + wire [17:0] Input2 = !input_ctrl[1] ? A : + !input_ctrl[0] ? D : B; + + wire [17:0] Input3 = !input_ctrl[0] ? B : D; + InnerBlend inner_blend1(op, Input1[5:0], Input2[5:0], Input3[5:0], Result[5:0]); + InnerBlend inner_blend2(op, Input1[11:6], Input2[11:6], Input3[11:6], Result[11:6]); + InnerBlend inner_blend3(op, Input1[17:12], Input2[17:12], Input3[17:12], Result[17:12]); +endmodule + + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +module Hq2x #(parameter LENGTH, parameter HALF_DEPTH) +( + input clk, + input ce_x4, + input [DWIDTH:0] inputpixel, + input mono, + input disable_hq2x, + input reset_frame, + input reset_line, + input [1:0] read_y, + input [AWIDTH+1:0] read_x, + output [DWIDTH:0] outpixel +); + + +localparam AWIDTH = `BITS_TO_FIT(LENGTH); +localparam DWIDTH = HALF_DEPTH ? 8 : 17; + +wire [5:0] hqTable[256] = '{ + 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 47, 35, 23, 15, 55, 39, + 19, 19, 26, 58, 19, 19, 26, 58, 23, 15, 35, 35, 23, 15, 7, 35, + 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 55, 39, 23, 15, 51, 43, + 19, 19, 26, 58, 19, 19, 26, 58, 23, 15, 51, 35, 23, 15, 7, 43, + 19, 19, 26, 11, 19, 19, 26, 11, 23, 61, 35, 35, 23, 61, 51, 35, + 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 51, 35, 23, 15, 51, 35, + 19, 19, 26, 11, 19, 19, 26, 11, 23, 61, 7, 35, 23, 61, 7, 43, + 19, 19, 26, 11, 19, 19, 26, 58, 23, 15, 51, 35, 23, 61, 7, 43, + 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 47, 35, 23, 15, 55, 39, + 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 51, 35, 23, 15, 51, 35, + 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 55, 39, 23, 15, 51, 43, + 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 51, 39, 23, 15, 7, 43, + 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 51, 35, 23, 15, 51, 39, + 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 51, 35, 23, 15, 7, 35, + 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 51, 35, 23, 15, 7, 43, + 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 7, 35, 23, 15, 7, 43 +}; + +reg [17:0] Prev0, Prev1, Prev2, Curr0, Curr1, Next0, Next1, Next2; +reg [17:0] A, B, D, F, G, H; +reg [7:0] pattern, nextpatt; +reg [1:0] i; +reg [7:0] y; + +wire curbuf = y[0]; +reg prevbuf = 0; +wire iobuf = !curbuf; + +wire diff0, diff1; +DiffCheck diffcheck0(Curr1, (i == 0) ? Prev0 : (i == 1) ? Curr0 : (i == 2) ? Prev2 : Next1, diff0); +DiffCheck diffcheck1(Curr1, (i == 0) ? Prev1 : (i == 1) ? Next0 : (i == 2) ? Curr2 : Next2, diff1); + +wire [7:0] new_pattern = {diff1, diff0, pattern[7:2]}; + +wire [17:0] X = (i == 0) ? A : (i == 1) ? Prev1 : (i == 2) ? Next1 : G; +wire [17:0] blend_result; +Blend blender(hqTable[nextpatt], disable_hq2x, Curr0, X, B, D, F, H, blend_result); + +reg Curr2_addr1; +reg [AWIDTH:0] Curr2_addr2; +wire [17:0] Curr2 = HALF_DEPTH ? h2rgb(Curr2tmp) : Curr2tmp; +wire [DWIDTH:0] Curr2tmp; + +reg [AWIDTH:0] wrin_addr2; +reg [DWIDTH:0] wrpix; +reg wrin_en; + +function [17:0] h2rgb; + input [8:0] v; +begin + h2rgb = mono ? {v[5:3],v[2:0], v[5:3],v[2:0], v[5:3],v[2:0]} : {v[8:6],v[8:6],v[5:3],v[5:3],v[2:0],v[2:0]}; +end +endfunction + +function [8:0] rgb2h; + input [17:0] v; +begin + rgb2h = mono ? {3'b000, v[17:15], v[14:12]} : {v[17:15], v[11:9], v[5:3]}; +end +endfunction + +hq2x_in #(.LENGTH(LENGTH), .DWIDTH(DWIDTH)) hq2x_in +( + .clk(clk), + + .rdaddr(Curr2_addr2), + .rdbuf(Curr2_addr1), + .q(Curr2tmp), + + .wraddr(wrin_addr2), + .wrbuf(iobuf), + .data(wrpix), + .wren(wrin_en) +); + +reg [1:0] wrout_addr1; +reg [AWIDTH+1:0] wrout_addr2; +reg wrout_en; +reg [DWIDTH:0] wrdata; + +hq2x_out #(.LENGTH(LENGTH), .DWIDTH(DWIDTH)) hq2x_out +( + .clk(clk), + + .rdaddr(read_x), + .rdbuf(read_y), + .q(outpixel), + + .wraddr(wrout_addr2), + .wrbuf(wrout_addr1), + .data(wrdata), + .wren(wrout_en) +); + +always @(posedge clk) begin + reg [AWIDTH:0] offs; + reg old_reset_line; + reg old_reset_frame; + + wrout_en <= 0; + wrin_en <= 0; + + if(ce_x4) begin + + pattern <= new_pattern; + + if(~&offs) begin + if (i == 0) begin + Curr2_addr1 <= prevbuf; + Curr2_addr2 <= offs; + end + if (i == 1) begin + Prev2 <= Curr2; + Curr2_addr1 <= curbuf; + Curr2_addr2 <= offs; + end + if (i == 2) begin + Next2 <= HALF_DEPTH ? h2rgb(inputpixel) : inputpixel; + wrpix <= inputpixel; + wrin_addr2 <= offs; + wrin_en <= 1; + end + if (i == 3) begin + offs <= offs + 1'd1; + end + + if(HALF_DEPTH) wrdata <= rgb2h(blend_result); + else wrdata <= blend_result; + + wrout_addr1 <= {curbuf, i[1]}; + wrout_addr2 <= {offs, i[1]^i[0]}; + wrout_en <= 1; + end + + if(i==3) begin + nextpatt <= {new_pattern[7:6], new_pattern[3], new_pattern[5], new_pattern[2], new_pattern[4], new_pattern[1:0]}; + {A, G} <= {Prev0, Next0}; + {B, F, H, D} <= {Prev1, Curr2, Next1, Curr0}; + {Prev0, Prev1} <= {Prev1, Prev2}; + {Curr0, Curr1} <= {Curr1, Curr2}; + {Next0, Next1} <= {Next1, Next2}; + end else begin + nextpatt <= {nextpatt[5], nextpatt[3], nextpatt[0], nextpatt[6], nextpatt[1], nextpatt[7], nextpatt[4], nextpatt[2]}; + {B, F, H, D} <= {F, H, D, B}; + end + + i <= i + 1'b1; + if(old_reset_line && ~reset_line) begin + old_reset_frame <= reset_frame; + offs <= 0; + i <= 0; + y <= y + 1'd1; + prevbuf <= curbuf; + if(old_reset_frame & ~reset_frame) begin + y <= 0; + prevbuf <= 0; + end + end + + old_reset_line <= reset_line; + end +end + +endmodule // Hq2x diff --git a/GCE - Vectrex_MiST/rtl/keyboard.v b/GCE - Vectrex_MiST/rtl/keyboard.v new file mode 100644 index 00000000..8dde73d6 --- /dev/null +++ b/GCE - Vectrex_MiST/rtl/keyboard.v @@ -0,0 +1,79 @@ + + +module keyboard +( + input clk, + input reset, + input ps2_kbd_clk, + input ps2_kbd_data, + + output reg[7:0] joystick +); + +reg [11:0] shift_reg = 12'hFFF; +wire[11:0] kdata = {ps2_kbd_data,shift_reg[11:1]}; +wire [7:0] kcode = kdata[9:2]; +reg release_btn = 0; + +reg [7:0] code; +reg input_strobe = 0; + +always @(negedge clk) begin + reg old_reset = 0; + + old_reset <= reset; + + if(~old_reset & reset)begin + joystick <= 0; + end + + if(input_strobe) begin + case(code) + 'h16: joystick[4] <= ~release_btn; // 1 + 'h1E: joystick[5] <= ~release_btn; // 2 + 'h26: joystick[6] <= ~release_btn; // 3 + 'h25: joystick[7] <= ~release_btn; // 4 + + 'h75: joystick[3] <= ~release_btn; // arrow up + 'h72: joystick[2] <= ~release_btn; // arrow down + 'h6B: joystick[1] <= ~release_btn; // arrow left + 'h74: joystick[0] <= ~release_btn; // arrow right + endcase + end +end + +always @(posedge clk) begin + reg [3:0] prev_clk = 0; + reg old_reset = 0; + reg action = 0; + + old_reset <= reset; + input_strobe <= 0; + + if(~old_reset & reset)begin + prev_clk <= 0; + shift_reg <= 12'hFFF; + end else begin + prev_clk <= {ps2_kbd_clk,prev_clk[3:1]}; + if(prev_clk == 1) begin + if (kdata[11] & ^kdata[10:2] & ~kdata[1] & kdata[0]) begin + shift_reg <= 12'hFFF; + if (kcode == 8'he0) ; + // Extended key code follows + else if (kcode == 8'hf0) + // Release code follows + action <= 1; + else begin + // Cancel extended/release flags for next time + action <= 0; + release_btn <= action; + code <= kcode; + input_strobe <= 1; + end + end else begin + shift_reg <= kdata; + end + end + end +end +endmodule diff --git a/GCE - Vectrex_MiST/rtl/m6522a.vhd b/GCE - Vectrex_MiST/rtl/m6522a.vhd new file mode 100644 index 00000000..b650d971 --- /dev/null +++ b/GCE - Vectrex_MiST/rtl/m6522a.vhd @@ -0,0 +1,903 @@ +-- +-- A simulation model of VIC20 hardware +-- Copyright (c) MikeJ - March 2003 +-- +-- 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. +-- +-- You are responsible for any legal issues arising from your use of this code. +-- +-- The latest version of this file can be found at: www.fpgaarcade.com +-- +-- Email vic20@fpgaarcade.com +-- +-- +-- Revision list +-- +-- Arnim Laeuger, 12-Jan-2009: +-- Ported to numeric_std and simulation fix for signal initializations +-- version 002 fix from Mark McDougall, untested +-- version 001 initial release +-- not very sure about the shift register, documentation is a bit light. +-- +-- DarFPGA, 08-fev-2018 - m6522a.vhd +-- fixe Port_B(7) control with respect to T1 and ACR(7) for vectrex. +-- + +library ieee ; + use ieee.std_logic_1164.all ; + use ieee.numeric_std.all; + +entity M6522 is + port ( + + I_RS : in std_logic_vector(3 downto 0); + I_DATA : in std_logic_vector(7 downto 0); + O_DATA : out std_logic_vector(7 downto 0); + O_DATA_OE_L : out std_logic; + + I_RW_L : in std_logic; + I_CS1 : in std_logic; + I_CS2_L : in std_logic; + + O_IRQ_L : out std_logic; -- note, not open drain + -- port a + I_CA1 : in std_logic; + I_CA2 : in std_logic; + O_CA2 : out std_logic; + O_CA2_OE_L : out std_logic; + + I_PA : in std_logic_vector(7 downto 0); + O_PA : out std_logic_vector(7 downto 0); + O_PA_OE_L : out std_logic_vector(7 downto 0); + + -- port b + I_CB1 : in std_logic; + O_CB1 : out std_logic; + O_CB1_OE_L : out std_logic; + + I_CB2 : in std_logic; + O_CB2 : out std_logic; + O_CB2_OE_L : out std_logic; + + I_PB : in std_logic_vector(7 downto 0); + O_PB : out std_logic_vector(7 downto 0); + O_PB_OE_L : out std_logic_vector(7 downto 0); + + I_P2_H : in std_logic; -- high for phase 2 clock ____----__ + RESET_L : in std_logic; + ENA_4 : in std_logic; -- clk enable + CLK : in std_logic + ); +end; + +architecture RTL of M6522 is + + signal phase : std_logic_vector(1 downto 0); + signal p2_h_t1 : std_logic; + signal cs : std_logic; + + -- registers + signal r_ddra : std_logic_vector(7 downto 0); + signal r_ora : std_logic_vector(7 downto 0); + signal r_ira : std_logic_vector(7 downto 0); + + signal r_ddrb : std_logic_vector(7 downto 0); + signal r_orb : std_logic_vector(7 downto 0); + signal r_orb_in : std_logic_vector(7 downto 0); -- DAR 2018-01-18 + signal r_irb : std_logic_vector(7 downto 0); + + signal r_t1l_l : std_logic_vector(7 downto 0) := (others => '0'); + signal r_t1l_h : std_logic_vector(7 downto 0) := (others => '0'); + signal r_t2l_l : std_logic_vector(7 downto 0) := (others => '0'); + signal r_t2l_h : std_logic_vector(7 downto 0) := (others => '0'); -- not in real chip + signal r_sr : std_logic_vector(7 downto 0); + signal r_acr : std_logic_vector(7 downto 0); + signal r_pcr : std_logic_vector(7 downto 0); + signal r_ifr : std_logic_vector(7 downto 0); + signal r_ier : std_logic_vector(6 downto 0); + + signal sr_write_ena : boolean; + signal sr_read_ena : boolean; + signal ifr_write_ena : boolean; + signal ier_write_ena : boolean; + signal clear_irq : std_logic_vector(7 downto 0); + signal load_data : std_logic_vector(7 downto 0); + + -- timer 1 + signal t1c : std_logic_vector(15 downto 0) := (others => '0'); + signal t1c_active : boolean; + signal t1c_done : boolean; + signal t1_w_reset_int : boolean; + signal t1_r_reset_int : boolean; + signal t1_load_counter : boolean; + signal t1_reload_counter : boolean; + signal t1_toggle : std_logic; + signal t1_irq : std_logic := '0'; + + -- timer 2 + signal t2c : std_logic_vector(15 downto 0) := (others => '0'); + signal t2c_active : boolean; + signal t2c_done : boolean; + signal t2_pb6 : std_logic; + signal t2_pb6_t1 : std_logic; + signal t2_w_reset_int : boolean; + signal t2_r_reset_int : boolean; + signal t2_load_counter : boolean; + signal t2_reload_counter : boolean; + signal t2_irq : std_logic := '0'; + signal t2_sr_ena : boolean; + + -- shift reg + signal sr_cnt : std_logic_vector(3 downto 0); + signal sr_cb1_oe_l : std_logic; + signal sr_cb1_out : std_logic; + signal sr_drive_cb2 : std_logic; + signal sr_strobe : std_logic; + signal sr_strobe_t1 : std_logic; + signal sr_strobe_falling : boolean; + signal sr_strobe_rising : boolean; + signal sr_irq : std_logic; + signal sr_out : std_logic; + signal sr_off_delay : std_logic; + + -- io + signal w_orb_hs : std_logic; + signal w_ora_hs : std_logic; + signal r_irb_hs : std_logic; + signal r_ira_hs : std_logic; + + signal ca_hs_sr : std_logic; + signal ca_hs_pulse : std_logic; + signal cb_hs_sr : std_logic; + signal cb_hs_pulse : std_logic; + + signal cb1_in_mux : std_logic; + signal ca1_ip_reg : std_logic; + signal cb1_ip_reg : std_logic; + signal ca1_int : boolean; + signal cb1_int : boolean; + signal ca1_irq : std_logic; + signal cb1_irq : std_logic; + + signal ca2_ip_reg : std_logic; + signal cb2_ip_reg : std_logic; + signal ca2_int : boolean; + signal cb2_int : boolean; + signal ca2_irq : std_logic; + signal cb2_irq : std_logic; + + signal final_irq : std_logic; +begin + + p_phase : process + begin + -- internal clock phase + wait until rising_edge(CLK); + if (ENA_4 = '1') then + p2_h_t1 <= I_P2_H; + if (p2_h_t1 = '0') and (I_P2_H = '1') then + phase <= "11"; + else + phase <= std_logic_vector(unsigned(phase) + 1); + end if; + end if; + end process; + + p_cs : process(I_CS1, I_CS2_L, I_P2_H) + begin + cs <= '0'; + if (I_CS1 = '1') and (I_CS2_L = '0') and (I_P2_H = '1') then + cs <= '1'; + end if; + end process; + + -- peripheral control reg (pcr) + -- 0 ca1 interrupt control (0 +ve edge, 1 -ve edge) + -- 3..1 ca2 operation + -- 000 input -ve edge + -- 001 independend interrupt input -ve edge + -- 010 input +ve edge + -- 011 independend interrupt input +ve edge + -- 100 handshake output + -- 101 pulse output + -- 110 low output + -- 111 high output + -- 7..4 as 3..0 for cb1,cb2 + + -- auxiliary control reg (acr) + -- 0 input latch PA (0 disable, 1 enable) + -- 1 input latch PB (0 disable, 1 enable) + -- 4..2 shift reg control + -- 000 disable + -- 001 shift in using t2 + -- 010 shift in using o2 + -- 011 shift in using ext clk + -- 100 shift out free running t2 rate + -- 101 shift out using t2 + -- 101 shift out using o2 + -- 101 shift out using ext clk + -- 5 t2 timer control (0 timed interrupt, 1 count down with pulses on pb6) + -- 7..6 t1 timer control + -- 00 timed interrupt each time t1 is loaded pb7 disable + -- 01 continuous interrupts pb7 disable + -- 00 timed interrupt each time t1 is loaded pb7 one shot output + -- 01 continuous interrupts pb7 square wave output + -- + + p_write_reg_reset : process(RESET_L, CLK) + begin + if (RESET_L = '0') then + r_ora <= x"00"; r_orb <= x"00"; + r_ddra <= x"00"; r_ddrb <= x"00"; + r_acr <= x"00"; r_pcr <= x"00"; + + w_orb_hs <= '0'; + w_ora_hs <= '0'; + elsif rising_edge(CLK) then + if (ENA_4 = '1') then + w_orb_hs <= '0'; + w_ora_hs <= '0'; + if (cs = '1') and (I_RW_L = '0') then + case I_RS is + when x"0" => r_orb <= I_DATA; w_orb_hs <= '1'; + r_orb_in <= I_DATA; -- DAR 2018-01-18 + when x"1" => r_ora <= I_DATA; w_ora_hs <= '1'; + when x"2" => r_ddrb <= I_DATA; + when x"3" => r_ddra <= I_DATA; + when x"B" => r_acr <= I_DATA; + when x"C" => r_pcr <= I_DATA; + when x"F" => r_ora <= I_DATA; + + when others => null; + end case; + end if; + + if r_acr(7) = '1' then -- DAR 2018-01-18 + if t1c_active = true then + r_orb(7) <= '0'; -- DAR 2018-01-18 + else + r_orb(7) <= '1'; -- DAR 2018-01-18 + end if; + else + r_orb(7) <= r_orb_in(7); -- DAR 2018-01-18 + end if; + + end if; + end if; + end process; + + p_write_reg : process + begin + wait until rising_edge(CLK); + if (ENA_4 = '1') then + t1_w_reset_int <= false; + t1_load_counter <= false; + + t2_w_reset_int <= false; + t2_load_counter <= false; + + load_data <= x"00"; + sr_write_ena <= false; + ifr_write_ena <= false; + ier_write_ena <= false; + + if (cs = '1') and (I_RW_L = '0') then + load_data <= I_DATA; + case I_RS is + when x"4" => r_t1l_l <= I_DATA; + when x"5" => r_t1l_h <= I_DATA; t1_w_reset_int <= true; + t1_load_counter <= true; + + when x"6" => r_t1l_l <= I_DATA; + when x"7" => r_t1l_h <= I_DATA; t1_w_reset_int <= true; + + when x"8" => r_t2l_l <= I_DATA; + when x"9" => r_t2l_h <= I_DATA; t2_w_reset_int <= true; + t2_load_counter <= true; + + when x"A" => sr_write_ena <= true; + when x"D" => ifr_write_ena <= true; + when x"E" => ier_write_ena <= true; + + when others => null; + end case; + end if; + end if; + end process; + + p_oe : process(cs, I_RW_L) + begin + O_DATA_OE_L <= '1'; + if (cs = '1') and (I_RW_L = '1') then + O_DATA_OE_L <= '0'; + end if; + end process; + + p_read : process(cs, I_RW_L, I_RS, r_irb, r_ira, r_ddrb, r_ddra, t1c, r_t1l_l, + r_t1l_h, t2c, r_sr, r_acr, r_pcr, r_ifr, r_ier, r_orb) + begin + t1_r_reset_int <= false; + t2_r_reset_int <= false; + sr_read_ena <= false; + r_irb_hs <= '0'; + r_ira_hs <= '0'; + O_DATA <= x"00"; -- default + if (cs = '1') and (I_RW_L = '1') then + case I_RS is + --when x"0" => O_DATA <= r_irb; r_irb_hs <= '1'; + -- fix from Mark McDougall, untested + when x"0" => O_DATA <= (r_irb and not r_ddrb) or (r_orb and r_ddrb); r_irb_hs <= '1'; + --when x"1" => O_DATA <= r_ira; r_ira_hs <= '1'; + when x"1" => O_DATA <= (r_ira and not r_ddra) or (r_ora and r_ddra); r_ira_hs <= '1'; + when x"2" => O_DATA <= r_ddrb; + when x"3" => O_DATA <= r_ddra; + when x"4" => O_DATA <= t1c( 7 downto 0); t1_r_reset_int <= true; + when x"5" => O_DATA <= t1c(15 downto 8); + when x"6" => O_DATA <= r_t1l_l; + when x"7" => O_DATA <= r_t1l_h; + when x"8" => O_DATA <= t2c( 7 downto 0); t2_r_reset_int <= true; + when x"9" => O_DATA <= t2c(15 downto 8); + when x"A" => O_DATA <= r_sr; sr_read_ena <= true; + when x"B" => O_DATA <= r_acr; + when x"C" => O_DATA <= r_pcr; + when x"D" => O_DATA <= r_ifr; + when x"E" => O_DATA <= ('0' & r_ier); + when x"F" => O_DATA <= r_ira; + when others => null; + end case; + end if; + + end process; + -- + -- IO + -- + p_ca1_cb1_sel : process(sr_cb1_oe_l, sr_cb1_out, I_CB1) + begin + -- if the shift register is enabled, cb1 may be an output + -- in this case, we should listen to the CB1_OUT for the interrupt + if (sr_cb1_oe_l = '1') then + cb1_in_mux <= I_CB1; + else + cb1_in_mux <= sr_cb1_out; + end if; + end process; + + p_ca1_cb1_int : process(r_pcr, ca1_ip_reg, I_CA1, cb1_ip_reg, cb1_in_mux) + begin + if (r_pcr(0) = '0') then -- ca1 control + -- negative edge + ca1_int <= (ca1_ip_reg = '1') and (I_CA1 = '0'); + else + -- positive edge + ca1_int <= (ca1_ip_reg = '0') and (I_CA1 = '1'); + end if; + + if (r_pcr(4) = '0') then -- cb1 control + -- negative edge + cb1_int <= (cb1_ip_reg = '1') and (cb1_in_mux = '0'); + else + -- positive edge + cb1_int <= (cb1_ip_reg = '0') and (cb1_in_mux = '1'); + end if; + end process; + + p_ca2_cb2_int : process(r_pcr, ca2_ip_reg, I_CA2, cb2_ip_reg, I_CB2) + begin + ca2_int <= false; + if (r_pcr(3) = '0') then -- ca2 input + if (r_pcr(2) = '0') then -- ca2 edge + -- negative edge + ca2_int <= (ca2_ip_reg = '1') and (I_CA2 = '0'); + else + -- positive edge + ca2_int <= (ca2_ip_reg = '0') and (I_CA2 = '1'); + end if; + end if; + + cb2_int <= false; + if (r_pcr(7) = '0') then -- cb2 input + if (r_pcr(6) = '0') then -- cb2 edge + -- negative edge + cb2_int <= (cb2_ip_reg = '1') and (I_CB2 = '0'); + else + -- positive edge + cb2_int <= (cb2_ip_reg = '0') and (I_CB2 = '1'); + end if; + end if; + end process; + + p_ca2_cb2 : process(RESET_L, CLK) + begin + if (RESET_L = '0') then + O_CA2 <= '0'; + O_CA2_OE_L <= '1'; + O_CB2 <= '0'; + O_CB2_OE_L <= '1'; + + ca_hs_sr <= '0'; + ca_hs_pulse <= '0'; + cb_hs_sr <= '0'; + cb_hs_pulse <= '0'; + elsif rising_edge(CLK) then + if (ENA_4 = '1') then + -- ca + if (phase = "00") and ((w_ora_hs = '1') or (r_ira_hs = '1')) then + ca_hs_sr <= '1'; + elsif ca1_int then + ca_hs_sr <= '0'; + end if; + + if (phase = "00") then + ca_hs_pulse <= w_ora_hs or r_ira_hs; + end if; + + O_CA2_OE_L <= not r_pcr(3); -- ca2 output + case r_pcr(3 downto 1) is + when "000" => O_CA2 <= '0'; -- input + when "001" => O_CA2 <= '0'; -- input + when "010" => O_CA2 <= '0'; -- input + when "011" => O_CA2 <= '0'; -- input + when "100" => O_CA2 <= not (ca_hs_sr); -- handshake + when "101" => O_CA2 <= not (ca_hs_pulse); -- pulse + when "110" => O_CA2 <= '0'; -- low + when "111" => O_CA2 <= '1'; -- high + when others => null; + end case; + + -- cb + if (phase = "00") and (w_orb_hs = '1') then + cb_hs_sr <= '1'; + elsif cb1_int then + cb_hs_sr <= '0'; + end if; + + if (phase = "00") then + cb_hs_pulse <= w_orb_hs; + end if; + + O_CB2_OE_L <= not (r_pcr(7) or sr_drive_cb2); -- cb2 output or serial + if (sr_drive_cb2 = '1') then -- serial output + O_CB2 <= sr_out; + else + case r_pcr(7 downto 5) is + when "000" => O_CB2 <= '0'; -- input + when "001" => O_CB2 <= '0'; -- input + when "010" => O_CB2 <= '0'; -- input + when "011" => O_CB2 <= '0'; -- input + when "100" => O_CB2 <= not (cb_hs_sr); -- handshake + when "101" => O_CB2 <= not (cb_hs_pulse); -- pulse + when "110" => O_CB2 <= '0'; -- low + when "111" => O_CB2 <= '1'; -- high + when others => null; + end case; + end if; + end if; + end if; + end process; + O_CB1 <= sr_cb1_out; + O_CB1_OE_L <= sr_cb1_oe_l; + + p_ca_cb_irq : process(RESET_L, CLK) + begin + if (RESET_L = '0') then + ca1_irq <= '0'; + ca2_irq <= '0'; + cb1_irq <= '0'; + cb2_irq <= '0'; + elsif rising_edge(CLK) then + if (ENA_4 = '1') then + -- not pretty + if ca1_int then + ca1_irq <= '1'; + elsif (r_ira_hs = '1') or (w_ora_hs = '1') or (clear_irq(1) = '1') then + ca1_irq <= '0'; + end if; + + if ca2_int then + ca2_irq <= '1'; + else + if (((r_ira_hs = '1') or (w_ora_hs = '1')) and (r_pcr(1) = '0')) or + (clear_irq(0) = '1') then + ca2_irq <= '0'; + end if; + end if; + + if cb1_int then + cb1_irq <= '1'; + elsif (r_irb_hs = '1') or (w_orb_hs = '1') or (clear_irq(4) = '1') then + cb1_irq <= '0'; + end if; + + if cb2_int then + cb2_irq <= '1'; + else + if (((r_irb_hs = '1') or (w_orb_hs = '1')) and (r_pcr(5) = '0')) or + (clear_irq(3) = '1') then + cb2_irq <= '0'; + end if; + end if; + end if; + end if; + end process; + + p_input_reg : process(RESET_L, CLK) + begin + if (RESET_L = '0') then + ca1_ip_reg <= '0'; + cb1_ip_reg <= '0'; + + ca2_ip_reg <= '0'; + cb2_ip_reg <= '0'; + + r_ira <= x"00"; + r_irb <= x"00"; + + elsif rising_edge(CLK) then + if (ENA_4 = '1') then + -- we have a fast clock, so we can have input registers + ca1_ip_reg <= I_CA1; + cb1_ip_reg <= cb1_in_mux; + + ca2_ip_reg <= I_CA2; + cb2_ip_reg <= I_CB2; + + if (r_acr(0) = '0') then + r_ira <= I_PA; + else -- enable latching + if ca1_int then + r_ira <= I_PA; + end if; + end if; + + if (r_acr(1) = '0') then + r_irb <= I_PB; + else -- enable latching + if cb1_int then + r_irb <= I_PB; + end if; + end if; + end if; + end if; + end process; + + + p_buffers : process(r_ddra, r_ora, r_ddrb, r_acr, r_orb) + begin + -- data direction reg (ddr) 0 = input, 1 = output + O_PA <= r_ora; + O_PA_OE_L <= not r_ddra; + + if (r_acr(7) = '1') then -- not clear if r_ddrb(7) must be 1 as well + O_PB_OE_L(7) <= '0'; -- an output if under t1 control + else + O_PB_OE_L(7) <= not (r_ddrb(7)); + end if; + + O_PB_OE_L(6 downto 0) <= not r_ddrb(6 downto 0); + O_PB(7 downto 0) <= r_orb(7 downto 0); + + end process; + -- + -- Timer 1 + -- + p_timer1_done : process + variable done : boolean; + begin + wait until rising_edge(CLK); + if (ENA_4 = '1') then + done := (t1c = x"0000"); + t1c_done <= done and (phase = "11"); + if (phase = "11") then + t1_reload_counter <= done and (r_acr(6) = '1'); + end if; + end if; + end process; + + p_timer1 : process + begin + wait until rising_edge(CLK); + if (ENA_4 = '1') then + if t1_load_counter or (t1_reload_counter and phase = "11") then + t1c( 7 downto 0) <= r_t1l_l; + t1c(15 downto 8) <= r_t1l_h; + elsif (phase="11") then + t1c <= std_logic_vector(unsigned(t1c) - 1); + end if; + + if t1_load_counter or t1_reload_counter then + t1c_active <= true; + elsif t1c_done then + t1c_active <= false; + end if; + + t1_toggle <= '0'; + if t1c_active and t1c_done then + t1_toggle <= '1'; + t1_irq <= '1'; + elsif t1_w_reset_int or t1_r_reset_int or (clear_irq(6) = '1') then + t1_irq <= '0'; + end if; + end if; + end process; + -- + -- Timer2 + -- + p_timer2_pb6_input : process + begin + wait until rising_edge(CLK); + if (ENA_4 = '1') then + if (phase = "01") then -- leading edge p2_h + t2_pb6 <= I_PB(6); + t2_pb6_t1 <= t2_pb6; + end if; + end if; + end process; + + p_timer2_done : process + variable done : boolean; + begin + wait until rising_edge(CLK); + if (ENA_4 = '1') then + done := (t2c = x"0000"); + t2c_done <= done and (phase = "11"); + if (phase = "11") then + t2_reload_counter <= done; + end if; + end if; + end process; + + p_timer2 : process + variable ena : boolean; + begin + wait until rising_edge(CLK); + if (ENA_4 = '1') then + if (r_acr(5) = '0') then + ena := true; + else + ena := (t2_pb6_t1 = '1') and (t2_pb6 = '0'); -- falling edge + end if; + + if t2_load_counter or (t2_reload_counter and phase = "11") then + -- not sure if t2c_reload should be here. Does timer2 just continue to + -- count down, or is it reloaded ? Reloaded makes more sense if using + -- it to generate a clock for the shift register. + t2c( 7 downto 0) <= r_t2l_l; + t2c(15 downto 8) <= r_t2l_h; + else + if (phase="11") and ena then -- or count mode + t2c <= std_logic_vector(unsigned(t2c) - 1); + end if; + end if; + + t2_sr_ena <= (t2c(7 downto 0) = x"00") and (phase = "11"); + + if t2_load_counter then + t2c_active <= true; + elsif t2c_done then + t2c_active <= false; + end if; + + + if t2c_active and t2c_done then + t2_irq <= '1'; + elsif t2_w_reset_int or t2_r_reset_int or (clear_irq(5) = '1') then + t2_irq <= '0'; + end if; + end if; + end process; + -- + -- Shift Register + -- + p_sr : process(RESET_L, CLK) + variable dir_out : std_logic; + variable ena : std_logic; + variable cb1_op : std_logic; + variable cb1_ip : std_logic; + variable use_t2 : std_logic; + variable free_run : std_logic; + variable sr_count_ena : boolean; + begin + if (RESET_L = '0') then + r_sr <= x"00"; + sr_drive_cb2 <= '0'; + sr_cb1_oe_l <= '1'; + sr_cb1_out <= '0'; + sr_strobe <= '1'; + sr_cnt <= "0000"; + sr_irq <= '0'; + sr_out <= '1'; + sr_off_delay <= '0'; + elsif rising_edge(CLK) then + if (ENA_4 = '1') then + -- decode mode + dir_out := r_acr(4); -- output on cb2 + cb1_op := '0'; + cb1_ip := '0'; + use_t2 := '0'; + free_run := '0'; + + case r_acr(4 downto 2) is + when "000" => ena := '0'; + when "001" => ena := '1'; cb1_op := '1'; use_t2 := '1'; + when "010" => ena := '1'; cb1_op := '1'; + when "011" => ena := '1'; cb1_ip := '1'; + when "100" => ena := '1'; use_t2 := '1'; free_run := '1'; + when "101" => ena := '1'; cb1_op := '1'; use_t2 := '1'; +-- when "110" => ena := '1'; free_run := '1'; -- hack + when "110" => ena := '1'; -- DAR 2018_01_24 + when "111" => ena := '1'; cb1_ip := '1'; + when others => null; + end case; + + -- clock select + if (ena = '0') then + sr_strobe <= '1'; + else + if (cb1_ip = '1') then + sr_strobe <= I_CB1; + else + if (sr_cnt(3) = '0') and (free_run = '0') then + sr_strobe <= '1'; + else + if ((use_t2 = '1') and t2_sr_ena) or + ((use_t2 = '0') and (phase = "00")) then + sr_strobe <= not sr_strobe; + end if; + end if; + end if; + end if; + + -- latch on rising edge, shift on falling edge + if sr_write_ena then + r_sr <= load_data; + elsif (ena = '1') then -- use shift reg + + if (dir_out = '0') then + -- input + if (sr_cnt(3) = '1') or (cb1_ip = '1') then + if sr_strobe_rising then + r_sr(0) <= I_CB2; + elsif sr_strobe_falling then + r_sr(7 downto 1) <= r_sr(6 downto 0); + end if; + end if; + sr_out <= '1'; + else + -- output + if (sr_cnt(3) = '1') or (sr_off_delay = '1') or (cb1_ip = '1') or (free_run = '1') then + if sr_strobe_falling then + r_sr(7 downto 1) <= r_sr(6 downto 0); + r_sr(0) <= r_sr(7); + sr_out <= r_sr(7); + end if; + else +-- sr_out <= '1'; + sr_out <= r_sr(7); -- DAR 2018-01-25 + end if; + end if; + end if; + + sr_count_ena := sr_strobe_rising; + + if sr_write_ena or sr_read_ena then + -- some documentation says sr bit in IFR must be set as well ? +-- sr_cnt <= "1000"; + sr_cnt <= "1001"; -- DAR 2018-01-25 + elsif sr_count_ena and (sr_cnt(3) = '1') then + sr_cnt <= std_logic_vector(unsigned(sr_cnt) + 1); + end if; + + if (phase = "00") then + sr_off_delay <= sr_cnt(3); -- give some hold time when shifting out + end if; + + if sr_count_ena and (sr_cnt = "1111") and (ena = '1') and (free_run = '0') then + sr_irq <= '1'; + elsif sr_write_ena or sr_read_ena or (clear_irq(2) = '1') then + sr_irq <= '0'; + end if; + + -- assign ops + sr_drive_cb2 <= dir_out; + sr_cb1_oe_l <= not cb1_op; + sr_cb1_out <= sr_strobe; + end if; + end if; + end process; + + p_sr_strobe_rise_fall : process + begin + wait until rising_edge(CLK); + if (ENA_4 = '1') then + sr_strobe_t1 <= sr_strobe; + sr_strobe_rising <= (sr_strobe_t1 = '0') and (sr_strobe = '1'); + sr_strobe_falling <= (sr_strobe_t1 = '1') and (sr_strobe = '0'); + end if; + end process; + -- + -- Interrupts + -- + p_ier : process(RESET_L, CLK) + begin + if (RESET_L = '0') then + r_ier <= "0000000"; + elsif rising_edge(CLK) then + if (ENA_4 = '1') then + if ier_write_ena then + if (load_data(7) = '1') then + -- set + r_ier <= r_ier or load_data(6 downto 0); + else + -- clear + r_ier <= r_ier and not load_data(6 downto 0); + end if; + end if; + end if; + end if; + end process; + + p_ifr : process(t1_irq, t2_irq, final_irq, ca1_irq, ca2_irq, sr_irq, + cb1_irq, cb2_irq) + begin + r_ifr(7) <= final_irq; + r_ifr(6) <= t1_irq; + r_ifr(5) <= t2_irq; + r_ifr(4) <= cb1_irq; + r_ifr(3) <= cb2_irq; + r_ifr(2) <= sr_irq; + r_ifr(1) <= ca1_irq; + r_ifr(0) <= ca2_irq; + + O_IRQ_L <= not final_irq; + end process; + + p_irq : process(RESET_L, CLK) + begin + if (RESET_L = '0') then + final_irq <= '0'; + elsif rising_edge(CLK) then + if (ENA_4 = '1') then + if ((r_ifr(6 downto 0) and r_ier(6 downto 0)) = "0000000") then + final_irq <= '0'; -- no interrupts + else + final_irq <= '1'; + end if; + end if; + end if; + end process; + + p_clear_irq : process(ifr_write_ena, load_data) + begin + clear_irq <= x"00"; + if ifr_write_ena then + clear_irq <= load_data; + end if; + end process; + +end architecture RTL; diff --git a/GCE - Vectrex_MiST/rtl/mist_io.v b/GCE - Vectrex_MiST/rtl/mist_io.v new file mode 100644 index 00000000..ad233a3b --- /dev/null +++ b/GCE - Vectrex_MiST/rtl/mist_io.v @@ -0,0 +1,491 @@ +// +// mist_io.v +// +// mist_io for the MiST board +// http://code.google.com/p/mist-board/ +// +// Copyright (c) 2014 Till Harbaum +// +// This source file is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This source file is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +/////////////////////////////////////////////////////////////////////// + +// +// Use buffer to access SD card. It's time-critical part. +// Made module synchroneous with 2 clock domains: clk_sys and SPI_SCK +// (Sorgelig) +// +// for synchronous projects default value for PS2DIV is fine for any frequency of system clock. +// clk_ps2 = clk_sys/(PS2DIV*2) +// + +module mist_io #(parameter STRLEN=0, parameter PS2DIV=100) +( + + // parameter STRLEN and the actual length of conf_str have to match + input [(8*STRLEN)-1:0] conf_str, + + // Global clock. It should be around 100MHz (higher is better). + input clk_sys, + + // Global SPI clock from ARM. 24MHz + input SPI_SCK, + + input CONF_DATA0, + input SPI_SS2, + output SPI_DO, + input SPI_DI, + + output reg [7:0] joystick_0, + output reg [7:0] joystick_1, + output reg [15:0] joystick_analog_0, + output reg [15:0] joystick_analog_1, + output [1:0] buttons, + output [1:0] switches, + output scandoubler_disable, + output ypbpr, + + output reg [31:0] status, + + // SD config + input sd_conf, + input sd_sdhc, + output img_mounted, // signaling that new image has been mounted + output reg [31:0] img_size, // size of image in bytes + + // SD block level access + input [31:0] sd_lba, + input sd_rd, + input sd_wr, + output reg sd_ack, + output reg sd_ack_conf, + + // SD byte level access. Signals for 2-PORT altsyncram. + output reg [8:0] sd_buff_addr, + output reg [7:0] sd_buff_dout, + input [7:0] sd_buff_din, + output reg sd_buff_wr, + + // ps2 keyboard emulation + output ps2_kbd_clk, + output reg ps2_kbd_data, + output ps2_mouse_clk, + output reg ps2_mouse_data, + input ps2_caps_led, + + // ARM -> FPGA download + output reg ioctl_download = 0, // signal indicating an active download + output reg [7:0] ioctl_index, // menu index used to upload the file + output ioctl_wr, + output reg [24:0] ioctl_addr, + output reg [7:0] ioctl_dout +); + +reg [7:0] b_data; +reg [6:0] sbuf; +reg [7:0] cmd; +reg [2:0] bit_cnt; // counts bits 0-7 0-7 ... +reg [9:0] byte_cnt; // counts bytes +reg [7:0] but_sw; +reg [2:0] stick_idx; + +reg mount_strobe = 0; +assign img_mounted = mount_strobe; + +assign buttons = but_sw[1:0]; +assign switches = but_sw[3:2]; +assign scandoubler_disable = but_sw[4]; +assign ypbpr = but_sw[5]; + +wire [7:0] spi_dout = { sbuf, SPI_DI}; + +// this variant of user_io is for 8 bit cores (type == a4) only +wire [7:0] core_type = 8'ha4; + +// command byte read by the io controller +wire [7:0] sd_cmd = { 4'h5, sd_conf, sd_sdhc, sd_wr, sd_rd }; + +reg spi_do; +assign SPI_DO = CONF_DATA0 ? 1'bZ : spi_do; + +wire [7:0] kbd_led = { 2'b01, 4'b0000, ps2_caps_led, 1'b1}; + +// drive MISO only when transmitting core id +always@(negedge SPI_SCK) begin + if(!CONF_DATA0) begin + // first byte returned is always core type, further bytes are + // command dependent + if(byte_cnt == 0) begin + spi_do <= core_type[~bit_cnt]; + + end else begin + case(cmd) + // reading config string + 8'h14: begin + // returning a byte from string + if(byte_cnt < STRLEN + 1) spi_do <= conf_str[{STRLEN - byte_cnt,~bit_cnt}]; + else spi_do <= 0; + end + + // reading sd card status + 8'h16: begin + if(byte_cnt == 1) spi_do <= sd_cmd[~bit_cnt]; + else if((byte_cnt >= 2) && (byte_cnt < 6)) spi_do <= sd_lba[{5-byte_cnt, ~bit_cnt}]; + else spi_do <= 0; + end + + // reading sd card write data + 8'h18: + spi_do <= b_data[~bit_cnt]; + + // reading keyboard LED status + 8'h1f: + spi_do <= kbd_led[~bit_cnt]; + + default: + spi_do <= 0; + endcase + end + end +end + +reg b_wr2,b_wr3; +always @(negedge clk_sys) begin + b_wr3 <= b_wr2; + sd_buff_wr <= b_wr3; +end + +// SPI receiver +always@(posedge SPI_SCK or posedge CONF_DATA0) begin + + if(CONF_DATA0) begin + b_wr2 <= 0; + bit_cnt <= 0; + byte_cnt <= 0; + sd_ack <= 0; + sd_ack_conf <= 0; + end else begin + b_wr2 <= 0; + + sbuf <= spi_dout[6:0]; + bit_cnt <= bit_cnt + 1'd1; + if(bit_cnt == 5) begin + if (byte_cnt == 0) sd_buff_addr <= 0; + if((byte_cnt != 0) & (sd_buff_addr != 511)) sd_buff_addr <= sd_buff_addr + 1'b1; + if((byte_cnt == 1) & ((cmd == 8'h17) | (cmd == 8'h19))) sd_buff_addr <= 0; + end + + // finished reading command byte + if(bit_cnt == 7) begin + if(~&byte_cnt) byte_cnt <= byte_cnt + 8'd1; + if(byte_cnt == 0) begin + cmd <= spi_dout; + + if(spi_dout == 8'h19) begin + sd_ack_conf <= 1; + sd_buff_addr <= 0; + end + if((spi_dout == 8'h17) || (spi_dout == 8'h18)) begin + sd_ack <= 1; + sd_buff_addr <= 0; + end + if(spi_dout == 8'h18) b_data <= sd_buff_din; + + mount_strobe <= 0; + + end else begin + + case(cmd) + // buttons and switches + 8'h01: but_sw <= spi_dout; + 8'h02: joystick_0 <= spi_dout; + 8'h03: joystick_1 <= spi_dout; + + // store incoming ps2 mouse bytes + 8'h04: begin + ps2_mouse_fifo[ps2_mouse_wptr] <= spi_dout; + ps2_mouse_wptr <= ps2_mouse_wptr + 1'd1; + end + + // store incoming ps2 keyboard bytes + 8'h05: begin + ps2_kbd_fifo[ps2_kbd_wptr] <= spi_dout; + ps2_kbd_wptr <= ps2_kbd_wptr + 1'd1; + end + + 8'h15: status[7:0] <= spi_dout; + + // send SD config IO -> FPGA + // flag that download begins + // sd card knows data is config if sd_dout_strobe is asserted + // with sd_ack still being inactive (low) + 8'h19, + // send sector IO -> FPGA + // flag that download begins + 8'h17: begin + sd_buff_dout <= spi_dout; + b_wr2 <= 1; + end + + 8'h18: b_data <= sd_buff_din; + + // joystick analog + 8'h1a: begin + // first byte is joystick index + if(byte_cnt == 1) stick_idx <= spi_dout[2:0]; + else if(byte_cnt == 2) begin + // second byte is x axis + if(stick_idx == 0) joystick_analog_0[15:8] <= spi_dout; + else if(stick_idx == 1) joystick_analog_1[15:8] <= spi_dout; + end else if(byte_cnt == 3) begin + // third byte is y axis + if(stick_idx == 0) joystick_analog_0[7:0] <= spi_dout; + else if(stick_idx == 1) joystick_analog_1[7:0] <= spi_dout; + end + end + + // notify image selection + 8'h1c: mount_strobe <= 1; + + // send image info + 8'h1d: if(byte_cnt<5) img_size[(byte_cnt-1)<<3 +:8] <= spi_dout; + + // status, 32bit version + 8'h1e: if(byte_cnt<5) status[(byte_cnt-1)<<3 +:8] <= spi_dout; + default: ; + endcase + end + end + end +end + + +/////////////////////////////// PS2 /////////////////////////////// +// 8 byte fifos to store ps2 bytes +localparam PS2_FIFO_BITS = 3; + +reg clk_ps2; +always @(negedge clk_sys) begin + integer cnt; + cnt <= cnt + 1'd1; + if(cnt == PS2DIV) begin + clk_ps2 <= ~clk_ps2; + cnt <= 0; + end +end + +// keyboard +reg [7:0] ps2_kbd_fifo[1<= 1)&&(ps2_kbd_tx_state < 9)) begin + ps2_kbd_data <= ps2_kbd_tx_byte[0]; // data bits + ps2_kbd_tx_byte[6:0] <= ps2_kbd_tx_byte[7:1]; // shift down + if(ps2_kbd_tx_byte[0]) + ps2_kbd_parity <= !ps2_kbd_parity; + end + + // transmission of parity + if(ps2_kbd_tx_state == 9) ps2_kbd_data <= ps2_kbd_parity; + + // transmission of stop bit + if(ps2_kbd_tx_state == 10) ps2_kbd_data <= 1; // stop bit is 1 + + // advance state machine + if(ps2_kbd_tx_state < 11) ps2_kbd_tx_state <= ps2_kbd_tx_state + 1'd1; + else ps2_kbd_tx_state <= 0; + end + end +end + +// mouse +reg [7:0] ps2_mouse_fifo[1<= 1)&&(ps2_mouse_tx_state < 9)) begin + ps2_mouse_data <= ps2_mouse_tx_byte[0]; // data bits + ps2_mouse_tx_byte[6:0] <= ps2_mouse_tx_byte[7:1]; // shift down + if(ps2_mouse_tx_byte[0]) + ps2_mouse_parity <= !ps2_mouse_parity; + end + + // transmission of parity + if(ps2_mouse_tx_state == 9) ps2_mouse_data <= ps2_mouse_parity; + + // transmission of stop bit + if(ps2_mouse_tx_state == 10) ps2_mouse_data <= 1; // stop bit is 1 + + // advance state machine + if(ps2_mouse_tx_state < 11) ps2_mouse_tx_state <= ps2_mouse_tx_state + 1'd1; + else ps2_mouse_tx_state <= 0; + end + end +end + + +/////////////////////////////// DOWNLOADING /////////////////////////////// + +reg [7:0] data_w; +reg [24:0] addr_w; +reg rclk = 0; + +localparam UIO_FILE_TX = 8'h53; +localparam UIO_FILE_TX_DAT = 8'h54; +localparam UIO_FILE_INDEX = 8'h55; + +// data_io has its own SPI interface to the io controller +always@(posedge SPI_SCK, posedge SPI_SS2) begin + reg [6:0] sbuf; + reg [7:0] cmd; + reg [4:0] cnt; + reg [24:0] addr; + + if(SPI_SS2) cnt <= 0; + else begin + rclk <= 0; + + // don't shift in last bit. It is evaluated directly + // when writing to ram + if(cnt != 15) sbuf <= { sbuf[5:0], SPI_DI}; + + // increase target address after write + if(rclk) addr <= addr + 1'd1; + + // count 0-7 8-15 8-15 ... + if(cnt < 15) cnt <= cnt + 1'd1; + else cnt <= 8; + + // finished command byte + if(cnt == 7) cmd <= {sbuf, SPI_DI}; + + // prepare/end transmission + if((cmd == UIO_FILE_TX) && (cnt == 15)) begin + // prepare + if(SPI_DI) begin + addr <= 0; + ioctl_download <= 1; + end else begin + addr_w <= addr; + ioctl_download <= 0; + end + end + + // command 0x54: UIO_FILE_TX + if((cmd == UIO_FILE_TX_DAT) && (cnt == 15)) begin + addr_w <= addr; + data_w <= {sbuf, SPI_DI}; + rclk <= 1; + end + + // expose file (menu) index + if((cmd == UIO_FILE_INDEX) && (cnt == 15)) ioctl_index <= {sbuf, SPI_DI}; + end +end + +assign ioctl_wr = |ioctl_wrd; +reg [1:0] ioctl_wrd; + +always@(negedge clk_sys) begin + reg rclkD, rclkD2; + + rclkD <= rclk; + rclkD2 <= rclkD; + ioctl_wrd<= {ioctl_wrd[0],1'b0}; + + if(rclkD & ~rclkD2) begin + ioctl_dout <= data_w; + ioctl_addr <= addr_w; + ioctl_wrd <= 2'b11; + end +end + +endmodule diff --git a/GCE - Vectrex_MiST/rtl/osd.v b/GCE - Vectrex_MiST/rtl/osd.v new file mode 100644 index 00000000..c62c10af --- /dev/null +++ b/GCE - Vectrex_MiST/rtl/osd.v @@ -0,0 +1,179 @@ +// A simple OSD implementation. Can be hooked up between a cores +// VGA output and the physical VGA pins + +module osd ( + // OSDs pixel clock, should be synchronous to cores pixel clock to + // avoid jitter. + input clk_sys, + + // SPI interface + input SPI_SCK, + input SPI_SS3, + input SPI_DI, + + // VGA signals coming from core + input [5:0] R_in, + input [5:0] G_in, + input [5:0] B_in, + input HSync, + input VSync, + + // VGA signals going to video connector + output [5:0] R_out, + output [5:0] G_out, + output [5:0] B_out +); + +parameter OSD_X_OFFSET = 10'd0; +parameter OSD_Y_OFFSET = 10'd0; +parameter OSD_COLOR = 3'd0; + +localparam OSD_WIDTH = 10'd256; +localparam OSD_HEIGHT = 10'd128; + +// ********************************************************************************* +// spi client +// ********************************************************************************* + +// this core supports only the display related OSD commands +// of the minimig +reg osd_enable; +(* ramstyle = "no_rw_check" *) reg [7:0] osd_buffer[2047:0]; // the OSD buffer itself + +// the OSD has its own SPI interface to the io controller +always@(posedge SPI_SCK, posedge SPI_SS3) begin + reg [4:0] cnt; + reg [10:0] bcnt; + reg [7:0] sbuf; + reg [7:0] cmd; + + if(SPI_SS3) begin + cnt <= 0; + bcnt <= 0; + end else begin + sbuf <= {sbuf[6:0], SPI_DI}; + + // 0:7 is command, rest payload + if(cnt < 15) cnt <= cnt + 1'd1; + else cnt <= 8; + + if(cnt == 7) begin + cmd <= {sbuf[6:0], SPI_DI}; + + // lower three command bits are line address + bcnt <= {sbuf[1:0], SPI_DI, 8'h00}; + + // command 0x40: OSDCMDENABLE, OSDCMDDISABLE + if(sbuf[6:3] == 4'b0100) osd_enable <= SPI_DI; + end + + // command 0x20: OSDCMDWRITE + if((cmd[7:3] == 5'b00100) && (cnt == 15)) begin + osd_buffer[bcnt] <= {sbuf[6:0], SPI_DI}; + bcnt <= bcnt + 1'd1; + end + end +end + +// ********************************************************************************* +// video timing and sync polarity anaylsis +// ********************************************************************************* + +// horizontal counter +reg [9:0] h_cnt; +reg [9:0] hs_low, hs_high; +wire hs_pol = hs_high < hs_low; +wire [9:0] dsp_width = hs_pol ? hs_low : hs_high; + +// vertical counter +reg [9:0] v_cnt; +reg [9:0] vs_low, vs_high; +wire vs_pol = vs_high < vs_low; +wire [9:0] dsp_height = vs_pol ? vs_low : vs_high; + +wire doublescan = (dsp_height>350); + +reg ce_pix; +always @(negedge clk_sys) begin + integer cnt = 0; + integer pixsz, pixcnt; + reg hs; + + cnt <= cnt + 1; + hs <= HSync; + + pixcnt <= pixcnt + 1; + if(pixcnt == pixsz) pixcnt <= 0; + ce_pix <= !pixcnt; + + if(hs && ~HSync) begin + cnt <= 0; + pixsz <= (cnt >> 9) - 1; + pixcnt <= 0; + ce_pix <= 1; + end +end + +always @(posedge clk_sys) begin + reg hsD, hsD2; + reg vsD, vsD2; + + if(ce_pix) begin + // bring hsync into local clock domain + hsD <= HSync; + hsD2 <= hsD; + + // falling edge of HSync + if(!hsD && hsD2) begin + h_cnt <= 0; + hs_high <= h_cnt; + end + + // rising edge of HSync + else if(hsD && !hsD2) begin + h_cnt <= 0; + hs_low <= h_cnt; + v_cnt <= v_cnt + 1'd1; + end else begin + h_cnt <= h_cnt + 1'd1; + end + + vsD <= VSync; + vsD2 <= vsD; + + // falling edge of VSync + if(!vsD && vsD2) begin + v_cnt <= 0; + vs_high <= v_cnt; + end + + // rising edge of VSync + else if(vsD && !vsD2) begin + v_cnt <= 0; + vs_low <= v_cnt; + end + end +end + +// area in which OSD is being displayed +wire [9:0] h_osd_start = ((dsp_width - OSD_WIDTH)>> 1) + OSD_X_OFFSET; +wire [9:0] h_osd_end = h_osd_start + OSD_WIDTH; +wire [9:0] v_osd_start = ((dsp_height- (OSD_HEIGHT<> 1) + OSD_Y_OFFSET; +wire [9:0] v_osd_end = v_osd_start + (OSD_HEIGHT<= h_osd_start) && (h_cnt < h_osd_end) && + (VSync != vs_pol) && (v_cnt >= v_osd_start) && (v_cnt < v_osd_end); + +reg [7:0] osd_byte; +always @(posedge clk_sys) if(ce_pix) osd_byte <= osd_buffer[{doublescan ? osd_vcnt[7:5] : osd_vcnt[6:4], osd_hcnt[7:0]}]; + +wire osd_pixel = osd_byte[doublescan ? osd_vcnt[4:2] : osd_vcnt[3:1]]; + +assign R_out = !osd_de ? R_in : {osd_pixel, osd_pixel, OSD_COLOR[2], R_in[5:3]}; +assign G_out = !osd_de ? G_in : {osd_pixel, osd_pixel, OSD_COLOR[1], G_in[5:3]}; +assign B_out = !osd_de ? B_in : {osd_pixel, osd_pixel, OSD_COLOR[0], B_in[5:3]}; + +endmodule diff --git a/GCE - Vectrex_MiST/rtl/pll.qip b/GCE - Vectrex_MiST/rtl/pll.qip new file mode 100644 index 00000000..afd958be --- /dev/null +++ b/GCE - Vectrex_MiST/rtl/pll.qip @@ -0,0 +1,4 @@ +set_global_assignment -name IP_TOOL_NAME "ALTPLL" +set_global_assignment -name IP_TOOL_VERSION "13.1" +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "pll.v"] +set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "pll.ppf"] diff --git a/GCE - Vectrex_MiST/rtl/pll.v b/GCE - Vectrex_MiST/rtl/pll.v new file mode 100644 index 00000000..cbd56df8 --- /dev/null +++ b/GCE - Vectrex_MiST/rtl/pll.v @@ -0,0 +1,376 @@ +// megafunction wizard: %ALTPLL% +// GENERATION: STANDARD +// VERSION: WM1.0 +// MODULE: altpll + +// ============================================================ +// File Name: pll.v +// Megafunction Name(s): +// altpll +// +// Simulation Library Files(s): +// altera_mf +// ============================================================ +// ************************************************************ +// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE! +// +// 13.1.0 Build 162 10/23/2013 SJ Web Edition +// ************************************************************ + + +//Copyright (C) 1991-2013 Altera Corporation +//Your use of Altera Corporation's design tools, logic functions +//and other software and tools, and its AMPP partner logic +//functions, and any output files from any of the foregoing +//(including device programming or simulation files), and any +//associated documentation or information are expressly subject +//to the terms and conditions of the Altera Program License +//Subscription Agreement, Altera MegaCore Function License +//Agreement, or other applicable license agreement, including, +//without limitation, that your use is for the sole purpose of +//programming logic devices manufactured by Altera and sold by +//Altera or its authorized distributors. Please refer to the +//applicable agreement for further details. + + +// synopsys translate_off +`timescale 1 ps / 1 ps +// synopsys translate_on +module pll ( + areset, + inclk0, + c0, + c1, + c2, + locked); + + input areset; + input inclk0; + output c0; + output c1; + output c2; + output locked; +`ifndef ALTERA_RESERVED_QIS +// synopsys translate_off +`endif + tri0 areset; +`ifndef ALTERA_RESERVED_QIS +// synopsys translate_on +`endif + + wire [4:0] sub_wire0; + wire sub_wire2; + wire [0:0] sub_wire7 = 1'h0; + wire [2:2] sub_wire4 = sub_wire0[2:2]; + wire [0:0] sub_wire3 = sub_wire0[0:0]; + wire [1:1] sub_wire1 = sub_wire0[1:1]; + wire c1 = sub_wire1; + wire locked = sub_wire2; + wire c0 = sub_wire3; + wire c2 = sub_wire4; + wire sub_wire5 = inclk0; + wire [1:0] sub_wire6 = {sub_wire7, sub_wire5}; + + altpll altpll_component ( + .areset (areset), + .inclk (sub_wire6), + .clk (sub_wire0), + .locked (sub_wire2), + .activeclock (), + .clkbad (), + .clkena ({6{1'b1}}), + .clkloss (), + .clkswitch (1'b0), + .configupdate (1'b0), + .enable0 (), + .enable1 (), + .extclk (), + .extclkena ({4{1'b1}}), + .fbin (1'b1), + .fbmimicbidir (), + .fbout (), + .fref (), + .icdrclk (), + .pfdena (1'b1), + .phasecounterselect ({4{1'b1}}), + .phasedone (), + .phasestep (1'b1), + .phaseupdown (1'b1), + .pllena (1'b1), + .scanaclr (1'b0), + .scanclk (1'b0), + .scanclkena (1'b1), + .scandata (1'b0), + .scandataout (), + .scandone (), + .scanread (1'b0), + .scanwrite (1'b0), + .sclkout0 (), + .sclkout1 (), + .vcooverrange (), + .vcounderrange ()); + defparam + altpll_component.bandwidth_type = "AUTO", + altpll_component.clk0_divide_by = 44, + altpll_component.clk0_duty_cycle = 50, + altpll_component.clk0_multiply_by = 41, + altpll_component.clk0_phase_shift = "0", + altpll_component.clk1_divide_by = 88, + altpll_component.clk1_duty_cycle = 50, + altpll_component.clk1_multiply_by = 41, + altpll_component.clk1_phase_shift = "0", + altpll_component.clk2_divide_by = 176, + altpll_component.clk2_duty_cycle = 50, + altpll_component.clk2_multiply_by = 41, + altpll_component.clk2_phase_shift = "0", + altpll_component.compensate_clock = "CLK0", + altpll_component.inclk0_input_frequency = 37037, + altpll_component.intended_device_family = "Cyclone III", + altpll_component.lpm_hint = "CBX_MODULE_PREFIX=pll", + altpll_component.lpm_type = "altpll", + altpll_component.operation_mode = "NORMAL", + altpll_component.pll_type = "AUTO", + altpll_component.port_activeclock = "PORT_UNUSED", + altpll_component.port_areset = "PORT_USED", + altpll_component.port_clkbad0 = "PORT_UNUSED", + altpll_component.port_clkbad1 = "PORT_UNUSED", + altpll_component.port_clkloss = "PORT_UNUSED", + altpll_component.port_clkswitch = "PORT_UNUSED", + altpll_component.port_configupdate = "PORT_UNUSED", + altpll_component.port_fbin = "PORT_UNUSED", + altpll_component.port_inclk0 = "PORT_USED", + altpll_component.port_inclk1 = "PORT_UNUSED", + altpll_component.port_locked = "PORT_USED", + altpll_component.port_pfdena = "PORT_UNUSED", + altpll_component.port_phasecounterselect = "PORT_UNUSED", + altpll_component.port_phasedone = "PORT_UNUSED", + altpll_component.port_phasestep = "PORT_UNUSED", + altpll_component.port_phaseupdown = "PORT_UNUSED", + altpll_component.port_pllena = "PORT_UNUSED", + altpll_component.port_scanaclr = "PORT_UNUSED", + altpll_component.port_scanclk = "PORT_UNUSED", + altpll_component.port_scanclkena = "PORT_UNUSED", + altpll_component.port_scandata = "PORT_UNUSED", + altpll_component.port_scandataout = "PORT_UNUSED", + altpll_component.port_scandone = "PORT_UNUSED", + altpll_component.port_scanread = "PORT_UNUSED", + altpll_component.port_scanwrite = "PORT_UNUSED", + altpll_component.port_clk0 = "PORT_USED", + altpll_component.port_clk1 = "PORT_USED", + altpll_component.port_clk2 = "PORT_USED", + altpll_component.port_clk3 = "PORT_UNUSED", + altpll_component.port_clk4 = "PORT_UNUSED", + altpll_component.port_clk5 = "PORT_UNUSED", + altpll_component.port_clkena0 = "PORT_UNUSED", + altpll_component.port_clkena1 = "PORT_UNUSED", + altpll_component.port_clkena2 = "PORT_UNUSED", + altpll_component.port_clkena3 = "PORT_UNUSED", + altpll_component.port_clkena4 = "PORT_UNUSED", + altpll_component.port_clkena5 = "PORT_UNUSED", + altpll_component.port_extclk0 = "PORT_UNUSED", + altpll_component.port_extclk1 = "PORT_UNUSED", + altpll_component.port_extclk2 = "PORT_UNUSED", + altpll_component.port_extclk3 = "PORT_UNUSED", + altpll_component.self_reset_on_loss_lock = "OFF", + altpll_component.width_clock = 5; + + +endmodule + +// ============================================================ +// CNX file retrieval info +// ============================================================ +// Retrieval info: PRIVATE: ACTIVECLK_CHECK STRING "0" +// Retrieval info: PRIVATE: BANDWIDTH STRING "1.000" +// Retrieval info: PRIVATE: BANDWIDTH_FEATURE_ENABLED STRING "1" +// Retrieval info: PRIVATE: BANDWIDTH_FREQ_UNIT STRING "MHz" +// Retrieval info: PRIVATE: BANDWIDTH_PRESET STRING "Low" +// Retrieval info: PRIVATE: BANDWIDTH_USE_AUTO STRING "1" +// Retrieval info: PRIVATE: BANDWIDTH_USE_PRESET STRING "0" +// Retrieval info: PRIVATE: CLKBAD_SWITCHOVER_CHECK STRING "0" +// Retrieval info: PRIVATE: CLKLOSS_CHECK STRING "0" +// Retrieval info: PRIVATE: CLKSWITCH_CHECK STRING "0" +// Retrieval info: PRIVATE: CNX_NO_COMPENSATE_RADIO STRING "0" +// Retrieval info: PRIVATE: CREATE_CLKBAD_CHECK STRING "0" +// Retrieval info: PRIVATE: CREATE_INCLK1_CHECK STRING "0" +// Retrieval info: PRIVATE: CUR_DEDICATED_CLK STRING "c0" +// Retrieval info: PRIVATE: CUR_FBIN_CLK STRING "c0" +// Retrieval info: PRIVATE: DEVICE_SPEED_GRADE STRING "8" +// Retrieval info: PRIVATE: DIV_FACTOR0 NUMERIC "44" +// Retrieval info: PRIVATE: DIV_FACTOR1 NUMERIC "88" +// Retrieval info: PRIVATE: DIV_FACTOR2 NUMERIC "176" +// Retrieval info: PRIVATE: DUTY_CYCLE0 STRING "50.00000000" +// Retrieval info: PRIVATE: DUTY_CYCLE1 STRING "50.00000000" +// Retrieval info: PRIVATE: DUTY_CYCLE2 STRING "50.00000000" +// Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE0 STRING "25.159090" +// Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE1 STRING "12.579545" +// Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE2 STRING "6.289773" +// Retrieval info: PRIVATE: EXPLICIT_SWITCHOVER_COUNTER STRING "0" +// Retrieval info: PRIVATE: EXT_FEEDBACK_RADIO STRING "0" +// Retrieval info: PRIVATE: GLOCKED_COUNTER_EDIT_CHANGED STRING "1" +// Retrieval info: PRIVATE: GLOCKED_FEATURE_ENABLED STRING "0" +// Retrieval info: PRIVATE: GLOCKED_MODE_CHECK STRING "0" +// Retrieval info: PRIVATE: GLOCK_COUNTER_EDIT NUMERIC "1048575" +// Retrieval info: PRIVATE: HAS_MANUAL_SWITCHOVER STRING "1" +// Retrieval info: PRIVATE: INCLK0_FREQ_EDIT STRING "27.000" +// Retrieval info: PRIVATE: INCLK0_FREQ_UNIT_COMBO STRING "MHz" +// Retrieval info: PRIVATE: INCLK1_FREQ_EDIT STRING "100.000" +// Retrieval info: PRIVATE: INCLK1_FREQ_EDIT_CHANGED STRING "1" +// Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_CHANGED STRING "1" +// Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_COMBO STRING "MHz" +// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone III" +// Retrieval info: PRIVATE: INT_FEEDBACK__MODE_RADIO STRING "1" +// Retrieval info: PRIVATE: LOCKED_OUTPUT_CHECK STRING "1" +// Retrieval info: PRIVATE: LONG_SCAN_RADIO STRING "1" +// Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE STRING "Not Available" +// Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE_DIRTY NUMERIC "0" +// Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT0 STRING "deg" +// Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT1 STRING "deg" +// Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT2 STRING "ps" +// Retrieval info: PRIVATE: MIG_DEVICE_SPEED_GRADE STRING "Any" +// Retrieval info: PRIVATE: MIRROR_CLK0 STRING "0" +// Retrieval info: PRIVATE: MIRROR_CLK1 STRING "0" +// Retrieval info: PRIVATE: MIRROR_CLK2 STRING "0" +// Retrieval info: PRIVATE: MULT_FACTOR0 NUMERIC "41" +// Retrieval info: PRIVATE: MULT_FACTOR1 NUMERIC "41" +// Retrieval info: PRIVATE: MULT_FACTOR2 NUMERIC "41" +// Retrieval info: PRIVATE: NORMAL_MODE_RADIO STRING "1" +// Retrieval info: PRIVATE: OUTPUT_FREQ0 STRING "25.17500000" +// Retrieval info: PRIVATE: OUTPUT_FREQ1 STRING "12.58750000" +// Retrieval info: PRIVATE: OUTPUT_FREQ2 STRING "6.29375000" +// Retrieval info: PRIVATE: OUTPUT_FREQ_MODE0 STRING "0" +// Retrieval info: PRIVATE: OUTPUT_FREQ_MODE1 STRING "0" +// Retrieval info: PRIVATE: OUTPUT_FREQ_MODE2 STRING "0" +// Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT0 STRING "MHz" +// Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT1 STRING "MHz" +// Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT2 STRING "MHz" +// Retrieval info: PRIVATE: PHASE_RECONFIG_FEATURE_ENABLED STRING "1" +// Retrieval info: PRIVATE: PHASE_RECONFIG_INPUTS_CHECK STRING "0" +// Retrieval info: PRIVATE: PHASE_SHIFT0 STRING "0.00000000" +// Retrieval info: PRIVATE: PHASE_SHIFT1 STRING "0.00000000" +// Retrieval info: PRIVATE: PHASE_SHIFT2 STRING "0.00000000" +// Retrieval info: PRIVATE: PHASE_SHIFT_STEP_ENABLED_CHECK STRING "0" +// Retrieval info: PRIVATE: PHASE_SHIFT_UNIT0 STRING "deg" +// Retrieval info: PRIVATE: PHASE_SHIFT_UNIT1 STRING "deg" +// Retrieval info: PRIVATE: PHASE_SHIFT_UNIT2 STRING "deg" +// Retrieval info: PRIVATE: PLL_ADVANCED_PARAM_CHECK STRING "0" +// Retrieval info: PRIVATE: PLL_ARESET_CHECK STRING "1" +// Retrieval info: PRIVATE: PLL_AUTOPLL_CHECK NUMERIC "1" +// Retrieval info: PRIVATE: PLL_ENHPLL_CHECK NUMERIC "0" +// Retrieval info: PRIVATE: PLL_FASTPLL_CHECK NUMERIC "0" +// Retrieval info: PRIVATE: PLL_FBMIMIC_CHECK STRING "0" +// Retrieval info: PRIVATE: PLL_LVDS_PLL_CHECK NUMERIC "0" +// Retrieval info: PRIVATE: PLL_PFDENA_CHECK STRING "0" +// Retrieval info: PRIVATE: PLL_TARGET_HARCOPY_CHECK NUMERIC "0" +// Retrieval info: PRIVATE: PRIMARY_CLK_COMBO STRING "inclk0" +// Retrieval info: PRIVATE: RECONFIG_FILE STRING "pll.mif" +// Retrieval info: PRIVATE: SACN_INPUTS_CHECK STRING "0" +// Retrieval info: PRIVATE: SCAN_FEATURE_ENABLED STRING "1" +// Retrieval info: PRIVATE: SELF_RESET_LOCK_LOSS STRING "0" +// Retrieval info: PRIVATE: SHORT_SCAN_RADIO STRING "0" +// Retrieval info: PRIVATE: SPREAD_FEATURE_ENABLED STRING "0" +// Retrieval info: PRIVATE: SPREAD_FREQ STRING "50.000" +// Retrieval info: PRIVATE: SPREAD_FREQ_UNIT STRING "KHz" +// Retrieval info: PRIVATE: SPREAD_PERCENT STRING "0.500" +// Retrieval info: PRIVATE: SPREAD_USE STRING "0" +// Retrieval info: PRIVATE: SRC_SYNCH_COMP_RADIO STRING "0" +// Retrieval info: PRIVATE: STICKY_CLK0 STRING "1" +// Retrieval info: PRIVATE: STICKY_CLK1 STRING "1" +// Retrieval info: PRIVATE: STICKY_CLK2 STRING "1" +// Retrieval info: PRIVATE: SWITCHOVER_COUNT_EDIT NUMERIC "1" +// Retrieval info: PRIVATE: SWITCHOVER_FEATURE_ENABLED STRING "1" +// Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0" +// Retrieval info: PRIVATE: USE_CLK0 STRING "1" +// Retrieval info: PRIVATE: USE_CLK1 STRING "1" +// Retrieval info: PRIVATE: USE_CLK2 STRING "1" +// Retrieval info: PRIVATE: USE_CLKENA0 STRING "0" +// Retrieval info: PRIVATE: USE_CLKENA1 STRING "0" +// Retrieval info: PRIVATE: USE_CLKENA2 STRING "0" +// Retrieval info: PRIVATE: USE_MIL_SPEED_GRADE NUMERIC "0" +// Retrieval info: PRIVATE: ZERO_DELAY_RADIO STRING "0" +// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all +// Retrieval info: CONSTANT: BANDWIDTH_TYPE STRING "AUTO" +// Retrieval info: CONSTANT: CLK0_DIVIDE_BY NUMERIC "44" +// Retrieval info: CONSTANT: CLK0_DUTY_CYCLE NUMERIC "50" +// Retrieval info: CONSTANT: CLK0_MULTIPLY_BY NUMERIC "41" +// Retrieval info: CONSTANT: CLK0_PHASE_SHIFT STRING "0" +// Retrieval info: CONSTANT: CLK1_DIVIDE_BY NUMERIC "88" +// Retrieval info: CONSTANT: CLK1_DUTY_CYCLE NUMERIC "50" +// Retrieval info: CONSTANT: CLK1_MULTIPLY_BY NUMERIC "41" +// Retrieval info: CONSTANT: CLK1_PHASE_SHIFT STRING "0" +// Retrieval info: CONSTANT: CLK2_DIVIDE_BY NUMERIC "176" +// Retrieval info: CONSTANT: CLK2_DUTY_CYCLE NUMERIC "50" +// Retrieval info: CONSTANT: CLK2_MULTIPLY_BY NUMERIC "41" +// Retrieval info: CONSTANT: CLK2_PHASE_SHIFT STRING "0" +// Retrieval info: CONSTANT: COMPENSATE_CLOCK STRING "CLK0" +// Retrieval info: CONSTANT: INCLK0_INPUT_FREQUENCY NUMERIC "37037" +// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone III" +// Retrieval info: CONSTANT: LPM_TYPE STRING "altpll" +// Retrieval info: CONSTANT: OPERATION_MODE STRING "NORMAL" +// Retrieval info: CONSTANT: PLL_TYPE STRING "AUTO" +// Retrieval info: CONSTANT: PORT_ACTIVECLOCK STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_ARESET STRING "PORT_USED" +// Retrieval info: CONSTANT: PORT_CLKBAD0 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_CLKBAD1 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_CLKLOSS STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_CLKSWITCH STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_CONFIGUPDATE STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_FBIN STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_INCLK0 STRING "PORT_USED" +// Retrieval info: CONSTANT: PORT_INCLK1 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_LOCKED STRING "PORT_USED" +// Retrieval info: CONSTANT: PORT_PFDENA STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_PHASECOUNTERSELECT STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_PHASEDONE STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_PHASESTEP STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_PHASEUPDOWN STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_PLLENA STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_SCANACLR STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_SCANCLK STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_SCANCLKENA STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_SCANDATA STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_SCANDATAOUT STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_SCANDONE STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_SCANREAD STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_SCANWRITE STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clk0 STRING "PORT_USED" +// Retrieval info: CONSTANT: PORT_clk1 STRING "PORT_USED" +// Retrieval info: CONSTANT: PORT_clk2 STRING "PORT_USED" +// Retrieval info: CONSTANT: PORT_clk3 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clk4 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clk5 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clkena0 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clkena1 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clkena2 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clkena3 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clkena4 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clkena5 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_extclk0 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_extclk1 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_extclk2 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_extclk3 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: SELF_RESET_ON_LOSS_LOCK STRING "OFF" +// Retrieval info: CONSTANT: WIDTH_CLOCK NUMERIC "5" +// Retrieval info: USED_PORT: @clk 0 0 5 0 OUTPUT_CLK_EXT VCC "@clk[4..0]" +// Retrieval info: USED_PORT: areset 0 0 0 0 INPUT GND "areset" +// Retrieval info: USED_PORT: c0 0 0 0 0 OUTPUT_CLK_EXT VCC "c0" +// Retrieval info: USED_PORT: c1 0 0 0 0 OUTPUT_CLK_EXT VCC "c1" +// Retrieval info: USED_PORT: c2 0 0 0 0 OUTPUT_CLK_EXT VCC "c2" +// Retrieval info: USED_PORT: inclk0 0 0 0 0 INPUT_CLK_EXT GND "inclk0" +// Retrieval info: USED_PORT: locked 0 0 0 0 OUTPUT GND "locked" +// Retrieval info: CONNECT: @areset 0 0 0 0 areset 0 0 0 0 +// Retrieval info: CONNECT: @inclk 0 0 1 1 GND 0 0 0 0 +// Retrieval info: CONNECT: @inclk 0 0 1 0 inclk0 0 0 0 0 +// Retrieval info: CONNECT: c0 0 0 0 0 @clk 0 0 1 0 +// Retrieval info: CONNECT: c1 0 0 0 0 @clk 0 0 1 1 +// Retrieval info: CONNECT: c2 0 0 0 0 @clk 0 0 1 2 +// Retrieval info: CONNECT: locked 0 0 0 0 @locked 0 0 0 0 +// Retrieval info: GEN_FILE: TYPE_NORMAL pll.v TRUE +// Retrieval info: GEN_FILE: TYPE_NORMAL pll.ppf TRUE +// Retrieval info: GEN_FILE: TYPE_NORMAL pll.inc FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL pll.cmp FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL pll.bsf FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL pll_inst.v FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL pll_bb.v FALSE +// Retrieval info: LIB_FILE: altera_mf +// Retrieval info: CBX_MODULE_PREFIX: ON diff --git a/GCE - Vectrex_MiST/rtl/scandoubler.v b/GCE - Vectrex_MiST/rtl/scandoubler.v new file mode 100644 index 00000000..36e71ed2 --- /dev/null +++ b/GCE - Vectrex_MiST/rtl/scandoubler.v @@ -0,0 +1,194 @@ +// +// scandoubler.v +// +// Copyright (c) 2015 Till Harbaum +// Copyright (c) 2017 Sorgelig +// +// 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 . + +// TODO: Delay vsync one line + +module scandoubler #(parameter LENGTH, parameter HALF_DEPTH) +( + // system interface + input clk_sys, + input ce_pix, + input ce_pix_actual, + + input hq2x, + + // shifter video interface + input hs_in, + input vs_in, + input line_start, + + input [DWIDTH:0] r_in, + input [DWIDTH:0] g_in, + input [DWIDTH:0] b_in, + input mono, + + // output interface + output reg hs_out, + output vs_out, + output [DWIDTH:0] r_out, + output [DWIDTH:0] g_out, + output [DWIDTH:0] b_out +); + +`define BITS_TO_FIT(N) ( \ + N <= 2 ? 0 : \ + N <= 4 ? 1 : \ + N <= 8 ? 2 : \ + N <= 16 ? 3 : \ + N <= 32 ? 4 : \ + N <= 64 ? 5 : \ + N <= 128 ? 6 : \ + N <= 256 ? 7 : \ + N <= 512 ? 8 : \ + N <=1024 ? 9 : 10 ) + +localparam DWIDTH = HALF_DEPTH ? 2 : 5; + +assign vs_out = vs_in; + +reg [2:0] phase; +reg [2:0] ce_div; +reg [7:0] pix_len = 0; +wire [7:0] pl = pix_len + 1'b1; + +reg ce_x1, ce_x4; +reg req_line_reset; +wire ls_in = hs_in | line_start; +always @(negedge clk_sys) begin + reg old_ce; + reg [2:0] ce_cnt; + + reg [7:0] pixsz2, pixsz4 = 0; + + old_ce <= ce_pix; + if(~&pix_len) pix_len <= pix_len + 1'd1; + + ce_x4 <= 0; + ce_x1 <= 0; + + // use such odd comparison to place c_x4 evenly if master clock isn't multiple 4. + if((pl == pixsz4) || (pl == pixsz2) || (pl == (pixsz2+pixsz4))) begin + phase <= phase + 1'd1; + ce_x4 <= 1; + end + + if(~old_ce & ce_pix) begin + pixsz2 <= {1'b0, pl[7:1]}; + pixsz4 <= {2'b00, pl[7:2]}; + ce_x1 <= 1; + ce_x4 <= 1; + pix_len <= 0; + phase <= phase + 1'd1; + + ce_cnt <= ce_cnt + 1'd1; + if(ce_pix_actual) begin + phase <= 0; + ce_div <= ce_cnt + 1'd1; + ce_cnt <= 0; + req_line_reset <= 0; + end + + if(ls_in) req_line_reset <= 1; + end +end + +reg ce_sd; +always @(*) begin + case(ce_div) + 2: ce_sd = !phase[0]; + 4: ce_sd = !phase[1:0]; + default: ce_sd <= 1; + endcase +end + +localparam AWIDTH = `BITS_TO_FIT(LENGTH); +Hq2x #(.LENGTH(LENGTH), .HALF_DEPTH(HALF_DEPTH)) Hq2x +( + .clk(clk_sys), + .ce_x4(ce_x4 & ce_sd), + .inputpixel({b_in,g_in,r_in}), + .mono(mono), + .disable_hq2x(~hq2x), + .reset_frame(vs_in), + .reset_line(req_line_reset), + .read_y(sd_line), + .read_x(sd_h_actual), + .outpixel({b_out,g_out,r_out}) +); + +reg [10:0] sd_h_actual; +always @(*) begin + case(ce_div) + 2: sd_h_actual = sd_h[10:1]; + 4: sd_h_actual = sd_h[10:2]; + default: sd_h_actual = sd_h; + endcase +end + +reg [10:0] sd_h; +reg [1:0] sd_line; +always @(posedge clk_sys) begin + + reg [11:0] hs_max,hs_rise,hs_ls; + reg [10:0] hcnt; + reg [11:0] sd_hcnt; + + reg hs, hs2, vs, ls; + + if(ce_x1) begin + hs <= hs_in; + ls <= ls_in; + + if(ls && !ls_in) hs_ls <= {hcnt,1'b1}; + + // falling edge of hsync indicates start of line + if(hs && !hs_in) begin + hs_max <= {hcnt,1'b1}; + hcnt <= 0; + if(ls && !ls_in) hs_ls <= {10'd0,1'b1}; + end else begin + hcnt <= hcnt + 1'd1; + end + + // save position of rising edge + if(!hs && hs_in) hs_rise <= {hcnt,1'b1}; + + vs <= vs_in; + if(vs && ~vs_in) sd_line <= 0; + end + + if(ce_x4) begin + hs2 <= hs_in; + + // output counter synchronous to input and at twice the rate + sd_hcnt <= sd_hcnt + 1'd1; + sd_h <= sd_h + 1'd1; + if(hs2 && !hs_in) sd_hcnt <= hs_max; + if(sd_hcnt == hs_max) sd_hcnt <= 0; + + // replicate horizontal sync at twice the speed + if(sd_hcnt == hs_max) hs_out <= 0; + if(sd_hcnt == hs_rise) hs_out <= 1; + + if(sd_hcnt == hs_ls) sd_h <= 0; + if(sd_hcnt == hs_ls) sd_line <= sd_line + 1'd1; + end +end + +endmodule diff --git a/GCE - Vectrex_MiST/rtl/vectrex.vhd b/GCE - Vectrex_MiST/rtl/vectrex.vhd new file mode 100644 index 00000000..7b290527 --- /dev/null +++ b/GCE - Vectrex_MiST/rtl/vectrex.vhd @@ -0,0 +1,805 @@ +--------------------------------------------------------------------------------- +-- Vectrex by Dar (darfpga@aol.fr) (27/12/2017) +-- http://darfpga.blogspot.fr +--------------------------------------------------------------------------------- +-- Educational use only +-- Do not redistribute synthetized file with roms +-- Do not redistribute roms whatever the form +-- Use at your own risk +--------------------------------------------------------------------------------- +--------------------------------------------------------------------------------- +-- gen_ram.vhd & io_ps2_keyboard +-- Copyright 2005-2008 by Peter Wendrich (pwsoft@syntiac.com) +-- http://www.syntiac.com/fpga64.html +--------------------------------------------------------------------------------- +-- VIA m6522 +-- Copyright (c) MikeJ - March 2003 +-- + modification +--------------------------------------------------------------------------------- +-- YM2149 (AY-3-8910) +-- Copyright (c) MikeJ - Jan 2005 +--------------------------------------------------------------------------------- +-- cpu09l_128 +-- Copyright (C) 2003 - 2010 John Kent +-- + modification +--------------------------------------------------------------------------------- +-- Use vectrex_de10_lite.sdc to compile (Timequest constraints) +-- /!\ +-- Don't forget to set device configuration mode with memory initialization +-- (Assignments/Device/Pin options/Configuration mode) +--------------------------------------------------------------------------------- +-- Vectrex beam control hardware +-- Uses via port_A, dac and capacitor to set beam x/y displacement speed +-- when done beam displacement is released (port_B_7 = 0) +-- beam displacement duration is controled by Timer 1 (that drive port_B_7) +-- or by 6809 instructions execution duration. +-- +-- Uses via port_A, dac and capacitor to set beam intensity before displacment + +-- Before drawing any object (or text) the beam position is reset to screen center. +-- via_CA2 is used to reset beam position. +-- +-- Uses via_CB2 to set pen ON/OFF. CB2 is always driven by via shift register (SR) +-- output. SR is loaded with 0xFF for plain line drawing. SR is loaded with 0x00 +-- for displacement with no drawing. SR is loaded with characters graphics +-- (character by character and line by line). SR is ALWAYS used in one shot mode +-- although SR bits are recirculated, SR shift stops on the last data bit (and +-- not on the first bit of data recirculated) +-- +-- Exec_rom uses line drawing with Timer 1 and FF/00 SR loading (FF or 00 with +-- recirculation always output respectively 1 or 0). Timer 1 timeout is checked +-- by software polling loop. +-- +-- Exec_rom draw characters in the following manner : start displacement and feed +-- SR with character grahics (at the right time) till the end of the complete line. +-- Then move down one line and then backward up to the begining of the next line +-- with no drawing. Then start drawing the second line... ans so on 7 times. +-- CPU has enough time to get the next character and the corresponding graphics +-- line data between each SR feed. T1 is not used. +-- +-- Most games seems to use those exec_rom routines. +-- +-- During cut scene of spike sound sample have to be interlaced (through dac) while +-- drawing. Spike uses it's own routine for that job. That routine prepare drawing +-- data (graphics and vx/vy speeds) within working ram before cut scene start to be +-- able to feed sound sample between each movement segment. T1 and SR are used but +-- T1 timeout is not check. CPU expect there is enough time from T1 start to next +-- dac modification (dac ouput is alway vx during move). Modifying dac before T1 +-- timeout will corrupt drawing. eg : when starting from @1230 (clr T1h), T1 must +-- have finished before reaching @11A4 (put sound sample value on dac). Drawing +-- characters with this routine is done by going backward between each character +-- graphic. Beam position is reset to screen center after/before each graphic line. +-- one sound sample is sent to dac after each character graphic. + +--------------------------------------------------------------------------------- +-- Video raster 588*444 < 256k running at 24MHz(25MHz) for VGA 640x480-60Hz +-- (horizontal display) +-- +-- requires 3 access per cycle => +-- | read video scan buffer| Write video scan buffer | write vector beam | +-- => 75Mhz ram access with single ram (13ns access time) +-- +-- implemented here as 4 separated buffers for 4 consecutives pixels +-- 4 phases acces at 24MHz(25MHz) +-- +-- 1) Read 1 pixel from each 4 buffers at video address => 4 pixels to be displayed +-- 2) Write one pixel at beam vector address (ie to one buffer only) +-- 3) Write 1 pixel to each 4 buffers at video address => 4 pixels updated +-- 4) Write one pixel at beam vector address (ie to one buffer only) +-- +-- thus video refresh (VGA) is ok : 4 pixels every 4 clock periods (25MHz) +-- vector beam is continuously written at 12MHz (seems to be ok) +-- +-- Each vram buffer is 64k (256k/4) x 2bits or 4bits +-- +-- 2bits witdh video raster (vram_width) buffer : +-- vector beam write value = 2 +-- video scan decrease this value by 1 after reading at each video frame (60Hz) +-- pixel is displayed full intensity as long as value not equal to 0 +-- +-- 4bits witdh video raster (vram_width) buffer : +-- vector beam write value = 2 in lower bits and intensity (0-3) in upper bits +-- video scan decrease the 2 lower bits by 1 after reading at each video frame (60Hz) +-- pixel is displayed upper bits intensity as long as lower bits value not equal to 0 +-- +--------------------------------------------------------------------------------- +library ieee; +use ieee.std_logic_1164.ALL; +use ieee.std_logic_unsigned.all; +use ieee.numeric_std.all; + +entity vectrex is +port +( + clock_24 : in std_logic; + clock_12 : in std_logic; + reset : in std_logic; + cpu_clock_o : out std_logic; + + video_r : out std_logic_vector(3 downto 0); + video_g : out std_logic_vector(3 downto 0); + video_b : out std_logic_vector(3 downto 0); + + video_hs : out std_logic; + video_vs : out std_logic; + video_blankn : out std_logic; + video_csync : out std_logic; + + audio_out : out std_logic_vector(9 downto 0); + cart_addr : out std_logic_vector(14 downto 0); + cart_do : in std_logic_vector( 7 downto 0); + cart_rd : out std_logic; + up_1 : in std_logic; + dn_1 : in std_logic; + lf_1 : in std_logic; + rt_1 : in std_logic; + pot_x_1 : in signed(7 downto 0); + pot_y_1 : in signed(7 downto 0); + + up_2 : in std_logic; + dn_2 : in std_logic; + lf_2 : in std_logic; + rt_2 : in std_logic; + pot_x_2 : in signed(7 downto 0); + pot_y_2 : in signed(7 downto 0); + + leds : out std_logic_vector(9 downto 0); + dbg_cpu_addr: out std_logic_vector(15 downto 0) + ); +end vectrex; + +architecture syn of vectrex is + +-------------------------------------------------------------- +-- Configuration +-------------------------------------------------------------- +-- Select catridge rom around line 700 +-------------------------------------------------------------- +-- intensity level : more or less ram +------------------------------------- +-- requires also comment/uncomment at two other places below +-- + constant vram_width : integer := 2; -- no intensity level +-- constant vram_width : integer := 4; -- 3 intensity level +-------------------------------------------------------------- +-- horizontal display (comment/uncomment whole section) +--------------------- +-- constant horizontal_display : integer := 1; +-- constant max_h : integer := 588; -- have to be multiple of 4 +-- constant max_v : integer := 444; +-- constant max_x : integer := 16875*8; +-- constant max_y : integer := 22500*8; +-- constant vram_addr_width : integer := 16; -- 64k vram buffer (x4) +-- constant video_start_h : integer := 160; +-- constant video_start_v : integer := 50; +-------------------------------------------------------------- +-- vertical display (comment/uncomment whole section) +------------------- + constant horizontal_display : integer := 0; + constant max_h : integer := 312; -- have to be multiple of 4 + constant max_v : integer := 416; + constant max_x : integer := 22500*8; + constant max_y : integer := 16875*8; + constant vram_addr_width : integer := 15; -- 32k vram buffer (x4) + constant video_start_h : integer := 300; + constant video_start_v : integer := 70; +-------------------------------------------------------------- + + signal clock_24n : std_logic; + signal clock_div : std_logic_vector(2 downto 0); + signal reset_n : std_logic; + + signal cpu_clock : std_logic; + signal cpu_addr : std_logic_vector(15 downto 0); + signal cpu_di : std_logic_vector( 7 downto 0); + signal cpu_do : std_logic_vector( 7 downto 0); + signal cpu_rw : std_logic; + signal cpu_irq : std_logic; + signal cpu_firq : std_logic; + signal cpu_fetch : std_logic; + + signal ram_cs : std_logic; + signal ram_do : std_logic_vector( 7 downto 0); + signal ram_we : std_logic; + + signal rom_cs : std_logic; + signal rom_do : std_logic_vector( 7 downto 0); + + signal cart_cs : std_logic; + --signal cart_do : std_logic_vector( 7 downto 0); + + signal via_cs_n : std_logic; + signal via_do : std_logic_vector(7 downto 0); + signal via_ca1_i : std_logic; + signal via_ca2_o : std_logic; + signal via_cb2_o : std_logic; + signal via_pa_i : std_logic_vector(7 downto 0); + signal via_pa_o : std_logic_vector(7 downto 0); + signal via_pb_i : std_logic_vector(7 downto 0); + signal via_pb_o : std_logic_vector(7 downto 0); + signal via_irq_n : std_logic; + signal via_en_4 : std_logic; + + signal sh_dac : std_logic; + signal dac_mux : std_logic_vector(2 downto 1); + signal zero_integrator_n : std_logic; + signal ramp_integrator_n : std_logic; + signal beam_blank_n : std_logic; + + signal dac : signed(8 downto 0); + signal dac_y : signed(8 downto 0); + signal dac_z : unsigned(7 downto 0); + signal ref_level : signed(8 downto 0); + signal z_level : std_logic_vector(1 downto 0); + signal dac_sound : std_logic_vector(7 downto 0); + + signal integrator_x : signed(19 downto 0); + signal integrator_y : signed(19 downto 0); + + signal shifted_x : signed(19 downto 0); + signal shifted_y : signed(19 downto 0); + + signal limited_x : unsigned(19 downto 0); + signal limited_y : unsigned(19 downto 0); + + signal beam_h : unsigned(9 downto 0); + signal beam_v : unsigned(9 downto 0); + + constant offset_y : integer := 0; + constant offset_x : integer := 0; + + constant scale_x : integer := max_v*256*256/(2*max_x); + constant scale_y : integer := max_h*256*256/(2*max_y); + + signal beam_blank_buffer : std_logic_vector(5 downto 0); + signal beam_blank_n_delayed : std_logic; + + signal beam_video_addr : std_logic_vector(19 downto 0); + signal scan_video_addr : std_logic_vector(19 downto 0); + signal video_addr : std_logic_vector(16 downto 0); + + signal phase : std_logic_vector(1 downto 0); + + signal video_we_0 : std_logic; + signal video_we_1 : std_logic; + signal video_we_2 : std_logic; + signal video_we_3 : std_logic; + signal video_rd : std_logic; + signal video_pixel: std_logic_vector(3 downto 0); + + signal read_0 : std_logic_vector(vram_width-1 downto 0); + signal read_0b: std_logic_vector(vram_width-1 downto 0); + signal read_1 : std_logic_vector(vram_width-1 downto 0); + signal read_1b: std_logic_vector(vram_width-1 downto 0); + signal read_2 : std_logic_vector(vram_width-1 downto 0); + signal read_2b: std_logic_vector(vram_width-1 downto 0); + signal read_3 : std_logic_vector(vram_width-1 downto 0); + signal read_3b: std_logic_vector(vram_width-1 downto 0); + signal pixel : std_logic_vector(vram_width-1 downto 0); + + signal write_0 : std_logic_vector(vram_width-1 downto 0); + signal write_1 : std_logic_vector(vram_width-1 downto 0); + signal write_2 : std_logic_vector(vram_width-1 downto 0); + signal write_3 : std_logic_vector(vram_width-1 downto 0); + + signal hcnt : std_logic_vector(9 downto 0); + signal vcnt : std_logic_vector(9 downto 0); + signal hcnt_video : std_logic_vector(9 downto 0); + signal vcnt_video : std_logic_vector(9 downto 0); + + signal hblank : std_logic; + signal vblank : std_logic; + + signal frame_line : std_logic; + + signal ay_do : std_logic_vector(7 downto 0); + signal ay_audio_muxed : std_logic_vector(7 downto 0); + signal ay_audio_chan : std_logic_vector(1 downto 0); + signal ay_chan_a : std_logic_vector(7 downto 0); + signal ay_chan_b : std_logic_vector(7 downto 0); + signal ay_chan_c : std_logic_vector(7 downto 0); + + signal pot : signed(7 downto 0); + signal compare : std_logic; + signal players_switches : std_logic_vector(7 downto 0); + +begin + +-- debug +process (clock_12, cpu_fetch) +begin + if rising_edge(clock_12) then + dbg_cpu_addr <= cpu_addr; + end if; +end process; + +leds(7 downto 0) <= dac_sound; +-------------------- + +-- clocks +reset_n <= not reset; +clock_24n <= not clock_24; + +process (clock_12, reset) + begin + if reset='1' then + clock_div <= "000"; + else + if rising_edge(clock_12) then + if clock_div = "111" then + clock_div <= "000"; + else + clock_div <= clock_div + '1'; + end if; + end if; + end if; +end process; + +via_en_4 <= clock_div(0); +cpu_clock <= clock_div(2); +cpu_clock_o <= clock_div(2); + +--static ADDRESS_MAP_START(vectrex_map, AS_PROGRAM, 8, vectrex_state ) +-- AM_RANGE(0x0000, 0x7fff) AM_NOP // cart area, handled at machine_start +-- AM_RANGE(0xc800, 0xcbff) AM_RAM AM_MIRROR(0x0400) AM_SHARE("gce_vectorram") +-- AM_RANGE(0xd000, 0xd7ff) AM_READWRITE(vectrex_via_r, vectrex_via_w) +-- AM_RANGE(0xe000, 0xffff) AM_ROM AM_REGION("maincpu", 0) +--ADDRESS_MAP_END + +-- chip select +cart_cs <= '1' when cpu_addr(15) = '0' else '0'; +ram_cs <= '1' when cpu_addr(15 downto 12) = X"C" else '0'; +via_cs_n <= '0' when cpu_addr(15 downto 12) = X"D" else '1'; +rom_cs <= '1' when cpu_addr(15 downto 13) = "111" else '0'; + +-- write enable working ram +ram_we <= '1' when cpu_rw = '0' and ram_cs = '1' else '0'; + +-- misc +cpu_irq <= not via_irq_n; +cpu_firq <= '0'; +cart_rd <= cart_cs; +cpu_di <= cart_do when cart_cs = '1' else + ram_do when ram_cs = '1' else + via_do when via_cs_n = '0' else + rom_do when rom_cs = '1' else + X"00"; + +via_pa_i <= ay_do; +via_pb_i <= "00"&compare&"00000"; + +-- players controls +players_switches <= not(rt_2&lf_2&dn_2&up_2&rt_1&lf_1&dn_1&up_1); + +with dac_mux select +pot <= pot_x_1 when "00", + pot_y_1 when "01", + pot_x_2 when "10", + pot_y_2 when others; + +compare <= '1' when (pot(7)&pot) > dac else '0'; + +-- beam control +sh_dac <= via_pb_o(0); +dac_mux <= via_pb_o(2 downto 1); +zero_integrator_n <= via_ca2_o; +ramp_integrator_n <= via_pb_o(7); +beam_blank_n <= via_cb2_o; + +dac <= signed(via_pa_o(7)&via_pa_o); -- must ensure sign extension for 0x80 value to be used in integrator equation + +z_level <= "11" when dac_z > 128 else + "10" when dac_Z > 64 else + "01" when dac_z > 0 else + "00"; + +process (clock_12, reset) + variable limit_n : std_logic; +begin + if reset='1' then + null; + else + if rising_edge(clock_12) then + if sh_dac = '0' then + case dac_mux is + when "00" => dac_y <= dac; + when "01" => ref_level <= dac; + when "10" => dac_z <= unsigned(via_pa_o); + when others => dac_sound <= via_pa_o; + end case; + end if; + + if zero_integrator_n = '0' then + integrator_x <= (others=>'0'); + integrator_y <= (others=>'0'); + else + if ramp_integrator_n = '0' then + if horizontal_display = 1 then + integrator_x <= integrator_x + (ref_level - dac); -- horizontal display + integrator_y <= integrator_y + (ref_level - dac_y); -- horizontal display + else + integrator_x <= integrator_x + (ref_level - dac_y); -- vertical display + integrator_y <= integrator_y - (ref_level - dac); -- vertical display + end if; + end if; + end if; + + -- set 'preserve registers' wihtin assignments editor to ease signaltap debuging + + shifted_x <= integrator_x+max_x-offset_x; + shifted_y <= integrator_y+max_y-offset_y; + + -- limit and scaling should be enhanced + + limit_n := '1'; + if shifted_x > 2*max_x then limited_x <= to_unsigned(2*max_x,20); + limit_n := '0'; + elsif shifted_x < 0 then limited_x <= (others=>'0'); + limit_n := '0'; + else limited_x <= unsigned(shifted_x); end if; + + if shifted_y > 2*max_y then limited_y <= to_unsigned(2*max_y,20); + limit_n := '0'; + elsif shifted_y < 0 then limited_y <= (others=>'0'); + limit_n := '0'; + else limited_y <= unsigned(shifted_y); end if; + + -- integer computation to try making rounding computation during division + + beam_v <= to_unsigned(to_integer(limited_x*to_unsigned(scale_x,10))/(256*256),10); + beam_h <= to_unsigned(to_integer(limited_y*to_unsigned(scale_y,10))/(256*256),10); + + beam_video_addr <= std_logic_vector(beam_v * to_unsigned(max_h,10) + beam_h); + + -- compense beam_video_addr computation delay vs beam_blank + + beam_blank_buffer <= beam_blank_buffer(4 downto 0) & beam_blank_n; + + beam_blank_n_delayed <= beam_blank_buffer(3) and limit_n; + + end if; + end if; +end process; + +-- video buffer +-- +-- 4 phases : (beam is fully asynchrone with video scanner) +-- +-- |read previous pixels| write beam pixel | write updated pixels | write beam pixel | +-- |from the 4 buffers | to one buffer | to the 4 buffers | to one buffer | +-- +-- Persistance simulation : +-- beam pixel are written as value 2 +-- updated pixels is written as previous value-1 +-- previous pixels are demuxed (serialized) and send to display +-- pixel is ON if value > 0 +-- +-- Intensity simulation : +-- if used (vram_witdh = 4) intensity is written by beam or read by scanner simultaneoulsy +-- with pixels. Its value is never modified. +-- +-- Compared to real hardware : +-- - fixed beam position has no effect on diplayed intensity. +-- - persitance management may show double trace for fast moving object +-- - flicker may appear where only lower intensity will be seen +-- +process (reset, clock_24) +begin + if reset='1' then + phase <= (others => '0'); + else + if rising_edge(clock_24) then + phase <= hcnt_video(1 downto 0); + + video_we_0 <= '0'; + video_we_1 <= '0'; + video_we_2 <= '0'; + video_we_3 <= '0'; + + case phase is + when "00" => + video_addr <= scan_video_addr(18 downto 2); + + when "10" => + video_addr <= scan_video_addr(18 downto 2); + if hblank = '0' and vblank = '0' then + if read_0(1 downto 0) > "00" then video_we_0 <= '1'; write_0 <= read_0 - '1'; end if; + if read_1(1 downto 0) > "00" then video_we_1 <= '1'; write_1 <= read_1 - '1'; end if; + if read_2(1 downto 0) > "00" then video_we_2 <= '1'; write_2 <= read_2 - '1'; end if; + if read_3(1 downto 0) > "00" then video_we_3 <= '1'; write_3 <= read_3 - '1'; end if; + end if; + + when others => + video_addr <= beam_video_addr(18 downto 2); + if beam_blank_n_delayed = '1' then + case beam_video_addr(1 downto 0) is + +-- uncomment when vram_width is 4 +-- when "00" => video_we_0 <= '1'; write_0 <= z_level&"10"; +-- when "01" => video_we_1 <= '1'; write_1 <= z_level&"10"; +-- when "10" => video_we_2 <= '1'; write_2 <= z_level&"10"; +-- when others => video_we_3 <= '1'; write_3 <= z_level&"10"; +-- +-- uncomment when vram_width is 2 + when "00" => video_we_0 <= '1'; write_0 <= "10"; + when "01" => video_we_1 <= '1'; write_1 <= "10"; + when "10" => video_we_2 <= '1'; write_2 <= "10"; + when others => video_we_3 <= '1'; write_3 <= "10"; +-- + end case; + end if; + end case; + + if phase = "01" then + read_0 <= read_0b; + read_1 <= read_1b; + read_2 <= read_2b; + read_3 <= read_3b; + end if; + + case phase is + when "10" => pixel <= read_0; + when "11" => pixel <= read_1; + when "00" => pixel <= read_2; + when others => pixel <= read_3; + end case; + + end if; + end if; +end process; + +-- uncomment when vram_width is 4 +-- +--video_pixel <= pixel(3 downto 2)&"00" when (pixel(1 downto 0) > "00") and (hblank = '0') else "0000"; +-- +-- uncomment when vram_width is 2 +-- +video_pixel <= "1100" when (pixel(1 downto 0) > "00") and (hblank = '0') else "0000"; +-- + +video_g <= video_pixel when frame_line = '0' else video_pixel or "0000"; +video_b <= video_pixel when frame_line = '0' else video_pixel or "0000"; +video_r <= video_pixel when frame_line = '0' else video_pixel or "0100"; + +buf_0 : entity work.gen_ram +generic map( dWidth => vram_width, aWidth => vram_addr_width) +port map( clk => clock_24n, we => video_we_0, addr => video_addr(vram_addr_width-1 downto 0), + d => write_0, q => read_0b); + +buf_1 : entity work.gen_ram +generic map( dWidth => vram_width, aWidth => vram_addr_width) +port map( clk => clock_24n, we => video_we_1, addr => video_addr(vram_addr_width-1 downto 0), + d => write_1, q => read_1b); + +buf_2 : entity work.gen_ram +generic map( dWidth => vram_width, aWidth => vram_addr_width) +port map( clk => clock_24n, we => video_we_2, addr => video_addr(vram_addr_width-1 downto 0), + d => write_2, q => read_2b); + +buf_3 : entity work.gen_ram +generic map( dWidth => vram_width, aWidth => vram_addr_width) +port map( clk => clock_24n, we => video_we_3, addr => video_addr(vram_addr_width-1 downto 0), + d => write_3, q => read_3b); + +------------------- +-- Video scanner -- +------------------- +process (reset, clock_24) +begin + if reset='1' then + hcnt <= (others => '0'); + vcnt <= (others => '0'); + else + if rising_edge(clock_24) then + + hcnt <= hcnt + '1'; + if hcnt = 799 then + hcnt <= (others => '0'); + if vcnt = 523 then + vcnt <= (others => '0'); + else + vcnt <= vcnt + '1'; + end if; + if vcnt = 523 then video_vs <= '0'; end if; + if vcnt = 1 then video_vs <= '1'; end if; + end if; + + if hcnt = 799 then video_hs <= '0'; end if; + if hcnt = 90 then video_hs <= '1'; end if; + + if vcnt_video = 0 or vcnt_video = (max_v-1) then + if hcnt_video = 3 then frame_line <= '1'; end if; + if hcnt_video = max_h+3 then frame_line <= '0'; end if; + elsif vcnt_video > 0 and vcnt_video < (max_v-1) then + if hcnt_video = 3 or hcnt_video = max_h+2 then frame_line <= '1'; + else frame_line <= '0'; end if; + else frame_line <= '0'; end if; + + if hcnt = video_start_h then + hcnt_video <= (others => '0'); + if vcnt = video_start_v then + vcnt_video <= (others => '0'); + else + vcnt_video <= vcnt_video + '1'; + end if; + else + hcnt_video <= hcnt_video + '1'; + end if; + + if hcnt_video = 3 then hblank <= '0'; end if; + if hcnt_video = max_h+3 then hblank <= '1'; end if; + if vcnt_video = 0 then vblank <= '0'; end if; + if vcnt_video = max_v then vblank <= '1'; end if; + + end if; + end if; +end process; + +video_blankn <= not (hblank or vblank); + +scan_video_addr <= vcnt_video * std_logic_vector(to_unsigned(max_h,10)) + hcnt_video; + +-- sound +process (cpu_clock) +begin + if rising_edge(cpu_clock) 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_out <= ("00"&ay_chan_a) + + ("00"&ay_chan_b) + + ("00"&ay_chan_c) + + ("00"&dac_sound); + +--------------------------- +-- components +--------------------------- + +-- microprocessor 6809 +main_cpu : entity work.cpu09 +port map( + clk => cpu_clock,-- E clock input (falling edge) + rst => reset, -- reset input (active high) + vma => open, -- valid memory address (active high) + lic_out => open, -- last instruction cycle (active high) + ifetch => open, -- instruction fetch cycle (active high) + opfetch => cpu_fetch,-- opcode fetch (active high) + ba => open, -- bus available (high on sync wait or DMA grant) + bs => open, -- bus status (high on interrupt or reset vector fetch or DMA grant) + addr => cpu_addr, -- address bus output + rw => cpu_rw, -- read not write output + data_out => cpu_do, -- data bus output + data_in => cpu_di, -- data bus input + irq => cpu_irq, -- interrupt request input (active high) + firq => cpu_firq, -- fast interrupt request input (active high) + nmi => '0', -- non maskable interrupt request input (active high) + halt => '0', -- halt input (active high) grants DMA + hold_in => '0' -- hold input (active high) extend bus cycle +); + + +cpu_prog_rom : entity work.vectrex_exec_prom +port map( + clk => cpu_clock, + addr => cpu_addr(12 downto 0), + data => rom_do +); + +-------------------------------------------------------------------- +-- Select cartridge here, select right rom length within port map + +--cart_do <= (others => '0'); -- no cartridge + +--cart_rom : entity work.vectrex_AGT_prom +--cart_rom : entity work.vectrex_scramble_prom +--cart_rom : entity work.vectrex_berzerk_prom +--cart_rom : entity work.vectrex_spacewar_prom +--cart_rom : entity work.vectrex_frogger_prom +--cart_rom : entity work.vectrex_polepos_prom +--cart_rom : entity work.vectrex_ripoff_prom +--cart_rom : entity work.vectrex_spike_prom +--cart_rom : entity work.vectrex_startrek_prom +--cart_rom : entity work.vectrex_vecmania1_prom +--cart_rom : entity work.vectrex_webwars_prom +--cart_rom : entity work.vectrex_wotr_prom + +--port map( +-- clk => cpu_clock, +-- addr => cpu_addr(11 downto 0), -- scramble,berzerk,ripoff,spacewar,startrek +-- addr => cpu_addr(12 downto 0), -- polepos,spike,webwars +-- addr => cpu_addr(13 downto 0), -- frogger,AGT +-- addr => cpu_addr(14 downto 0), -- vecmania,wotr + --data => cart_do +--); +-------------------------------------------------------------------- + + cart_addr <= cpu_addr(14 downto 0); + +working_ram : entity work.gen_ram +generic map( dWidth => 8, aWidth => 10) +port map( + clk => cpu_clock, + we => ram_we, + addr => cpu_addr(9 downto 0), + d => cpu_do, + q => ram_do +); + +via6522_inst : entity work.M6522 +port map( + I_RS => cpu_addr(3 downto 0), + I_DATA => cpu_do, + O_DATA => via_do, + O_DATA_OE_L => open, + + I_RW_L => cpu_rw, + I_CS1 => cpu_addr(12), + I_CS2_L => via_cs_n, + + O_IRQ_L => via_irq_n, + + -- port a + I_CA1 => via_ca1_i, + I_CA2 => '0', + O_CA2 => via_ca2_o, + O_CA2_OE_L => open, + + I_PA => via_pa_i, + O_PA => via_pa_o, + O_PA_OE_L => open, + + -- port b + I_CB1 => '0', + O_CB1 => open, + O_CB1_OE_L => open, + + I_CB2 => '0', + O_CB2 => via_cb2_o, + O_CB2_OE_L => open, + + I_PB => via_pb_i, + O_PB => via_pb_o, + O_PB_OE_L => open, + + RESET_L => reset_n, + CLK => clock_12, + I_P2_H => cpu_clock, -- high for phase 2 clock ____----__ + 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 => '0', -- in std_logic; + + O_AUDIO => ay_audio_muxed, -- out std_logic_vector(7 downto 0); + O_CHAN => ay_audio_chan, -- out std_logic_vector(1 downto 0); + + -- port a + I_IOA => players_switches, -- in std_logic_vector(7 downto 0); + O_IOA => open, -- out std_logic_vector(7 downto 0); + O_IOA_OE_L => open, -- 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; + + ENA => '1', --cpu_ena, -- in std_logic; -- clock enable for higher speed operation + RESET_L => reset_n, -- in std_logic; + CLK => cpu_clock -- in std_logic -- note 6 Mhz +); + +end SYN; diff --git a/GCE - Vectrex_MiST/rtl/vectrex_exec_prom.vhd b/GCE - Vectrex_MiST/rtl/vectrex_exec_prom.vhd new file mode 100644 index 00000000..4431ba3c --- /dev/null +++ b/GCE - Vectrex_MiST/rtl/vectrex_exec_prom.vhd @@ -0,0 +1,534 @@ +library ieee; +use ieee.std_logic_1164.all,ieee.numeric_std.all; + +entity vectrex_exec_prom is +port ( + clk : in std_logic; + addr : in std_logic_vector(12 downto 0); + data : out std_logic_vector(7 downto 0) +); +end entity; + +architecture prom of vectrex_exec_prom is + type rom is array(0 to 8191) of std_logic_vector(7 downto 0); + signal rom_data: rom := ( + X"ED",X"77",X"F8",X"50",X"30",X"E8",X"4D",X"49",X"4E",X"45",X"80",X"F8",X"50",X"00",X"DE",X"53", + X"54",X"4F",X"52",X"4D",X"80",X"00",X"8E",X"C8",X"83",X"6F",X"80",X"8C",X"CB",X"C5",X"26",X"F9", + X"BD",X"E8",X"E3",X"7C",X"C8",X"24",X"86",X"BB",X"B7",X"C8",X"80",X"8E",X"01",X"01",X"BF",X"C8", + X"81",X"8E",X"C8",X"83",X"6F",X"80",X"8C",X"CB",X"70",X"26",X"F9",X"20",X"00",X"BD",X"F1",X"AF", + X"CC",X"02",X"00",X"BD",X"F7",X"A9",X"0A",X"79",X"0F",X"56",X"0F",X"9B",X"8E",X"C8",X"A8",X"BD", + X"F8",X"4F",X"8E",X"C8",X"AF",X"BD",X"F8",X"4F",X"8E",X"C8",X"F9",X"BD",X"F8",X"4F",X"CC",X"00", + X"01",X"BD",X"F8",X"7C",X"8E",X"C9",X"00",X"BD",X"F8",X"4F",X"CC",X"00",X"01",X"BD",X"F8",X"7C", + X"8E",X"ED",X"AB",X"9F",X"C4",X"9F",X"C6",X"86",X"05",X"97",X"D9",X"97",X"DA",X"97",X"DB",X"20", + X"24",X"BD",X"E8",X"66",X"10",X"8E",X"C8",X"C4",X"96",X"9B",X"AE",X"A6",X"30",X"04",X"AF",X"A6", + X"8E",X"ED",X"A7",X"96",X"9B",X"AE",X"86",X"A6",X"05",X"84",X"03",X"26",X"02",X"0C",X"D9",X"CC", + X"00",X"01",X"BD",X"F8",X"7C",X"BD",X"E7",X"E4",X"8E",X"C8",X"C4",X"96",X"9B",X"AE",X"86",X"A6", + X"84",X"2B",X"05",X"BD",X"E1",X"29",X"20",X"41",X"DC",X"F0",X"83",X"00",X"01",X"DD",X"F0",X"27", + X"14",X"34",X"08",X"BD",X"F1",X"AA",X"BD",X"EA",X"CF",X"CE",X"EE",X"2F",X"BD",X"EA",X"9D",X"35", + X"08",X"96",X"0F",X"27",X"24",X"8E",X"C8",X"A8",X"CE",X"CB",X"EB",X"BD",X"F8",X"D8",X"8E",X"C8", + X"AF",X"CE",X"CB",X"EB",X"BD",X"F8",X"D8",X"DC",X"F0",X"10",X"26",X"FF",X"44",X"BD",X"F1",X"8B", + X"0F",X"3B",X"10",X"CE",X"CB",X"EA",X"7E",X"F0",X"1C",X"34",X"08",X"BD",X"EA",X"F0",X"BD",X"E5", + X"1E",X"BD",X"E2",X"62",X"BD",X"E4",X"B8",X"BD",X"E3",X"53",X"35",X"08",X"BD",X"EB",X"43",X"BD", + X"EC",X"46",X"BD",X"EC",X"95",X"BD",X"E6",X"47",X"25",X"DF",X"96",X"BD",X"10",X"27",X"FF",X"61", + X"96",X"BE",X"10",X"26",X"FF",X"92",X"7E",X"E0",X"A5",X"9F",X"C2",X"CC",X"7F",X"00",X"DD",X"DC", + X"97",X"B7",X"86",X"20",X"97",X"9C",X"8E",X"E1",X"E7",X"9F",X"9D",X"8E",X"C9",X"33",X"9F",X"B9", + X"86",X"1D",X"97",X"B8",X"0F",X"56",X"CE",X"ED",X"77",X"BD",X"F6",X"8D",X"34",X"08",X"BD",X"E7", + X"11",X"BD",X"F6",X"87",X"96",X"26",X"85",X"01",X"26",X"02",X"0A",X"B7",X"BD",X"EA",X"F0",X"BD", + X"EA",X"CF",X"BD",X"F2",X"89",X"BD",X"E5",X"1E",X"BD",X"F2",X"A5",X"F6",X"C8",X"B7",X"27",X"1C", + X"8E",X"EF",X"26",X"10",X"BE",X"C8",X"DC",X"BD",X"EA",X"7F",X"8E",X"EF",X"5D",X"BD",X"EA",X"7F", + X"8E",X"EF",X"94",X"BD",X"EA",X"7F",X"35",X"08",X"0A",X"DC",X"20",X"C0",X"35",X"08",X"0F",X"9C", + X"86",X"04",X"97",X"B7",X"86",X"7F",X"97",X"B8",X"96",X"B7",X"27",X"4A",X"D6",X"B8",X"27",X"04", + X"0A",X"B8",X"20",X"12",X"D6",X"26",X"C4",X"1F",X"26",X"0C",X"4A",X"97",X"B7",X"9E",X"C2",X"A6", + X"86",X"C6",X"03",X"BD",X"E9",X"A1",X"34",X"08",X"BD",X"EA",X"F0",X"BD",X"F2",X"A9",X"CE",X"EE", + X"20",X"BD",X"EA",X"9D",X"10",X"8E",X"E0",X"F8",X"CE",X"ED",X"A7",X"B6",X"C8",X"9B",X"EE",X"C6", + X"BD",X"EA",X"A8",X"BD",X"E5",X"1E",X"BD",X"E2",X"62",X"BD",X"E4",X"B8",X"35",X"08",X"BD",X"EB", + X"43",X"BD",X"E6",X"47",X"20",X"B2",X"39",X"0A",X"B8",X"27",X"4E",X"0C",X"ED",X"BD",X"F5",X"17", + X"84",X"07",X"8B",X"04",X"97",X"9C",X"DE",X"B9",X"86",X"80",X"A7",X"C4",X"DC",X"DC",X"8B",X"08", + X"A7",X"44",X"6F",X"45",X"E7",X"46",X"6F",X"47",X"BD",X"F5",X"17",X"4D",X"2B",X"0C",X"81",X"10", + X"2C",X"02",X"8B",X"0C",X"81",X"60",X"2F",X"0E",X"20",X"EE",X"81",X"F0",X"2F",X"02",X"80",X"0C", + X"81",X"A0",X"2C",X"02",X"20",X"E2",X"A7",X"C8",X"11",X"1F",X"89",X"1D",X"8A",X"01",X"A7",X"C8", + X"10",X"6F",X"42",X"31",X"C8",X"12",X"10",X"9F",X"B9",X"39",X"00",X"02",X"07",X"10",X"00",X"20", + X"18",X"10",X"01",X"00",X"05",X"00",X"03",X"25",X"07",X"50",X"00",X"00",X"01",X"00",X"00",X"35", + X"00",X"00",X"00",X"00",X"04",X"04",X"08",X"08",X"0D",X"0D",X"EE",X"3D",X"EE",X"53",X"EE",X"6F", + X"EE",X"8E",X"34",X"08",X"86",X"C8",X"1F",X"8B",X"96",X"BD",X"10",X"26",X"00",X"9C",X"96",X"EE", + X"10",X"26",X"00",X"A7",X"96",X"13",X"10",X"26",X"00",X"92",X"96",X"14",X"27",X"32",X"96",X"D4", + X"91",X"D6",X"27",X"1C",X"91",X"D8",X"27",X"08",X"96",X"D5",X"27",X"14",X"96",X"D7",X"26",X"20", + X"96",X"D7",X"8B",X"0C",X"81",X"7F",X"22",X"18",X"97",X"D7",X"96",X"D4",X"97",X"D8",X"20",X"0E", + X"96",X"D5",X"8B",X"0C",X"81",X"7F",X"22",X"08",X"97",X"D5",X"96",X"D4",X"97",X"D6",X"0C",X"F2", + X"96",X"D5",X"27",X"0E",X"80",X"02",X"97",X"D5",X"D6",X"D6",X"BD",X"E7",X"B5",X"10",X"9F",X"CC", + X"9F",X"CE",X"96",X"D7",X"27",X"0E",X"80",X"02",X"97",X"D7",X"D6",X"D8",X"BD",X"E7",X"B5",X"10", + X"9F",X"D0",X"9F",X"D2",X"DC",X"C8",X"D3",X"CC",X"D3",X"D0",X"DD",X"C8",X"DC",X"CA",X"D3",X"CE", + X"D3",X"D2",X"DD",X"CA",X"96",X"1B",X"27",X"0F",X"2B",X"04",X"0A",X"D4",X"20",X"06",X"0C",X"D4", + X"20",X"02",X"34",X"08",X"BD",X"E8",X"4C",X"86",X"D0",X"1F",X"8B",X"BD",X"F2",X"A5",X"C6",X"0C", + X"10",X"8E",X"C8",X"C8",X"8E",X"CB",X"89",X"BD",X"EA",X"8D",X"35",X"88",X"86",X"80",X"97",X"EE", + X"BD",X"F5",X"17",X"84",X"03",X"8B",X"03",X"97",X"EF",X"0C",X"F6",X"96",X"EE",X"2A",X"19",X"0A", + X"EF",X"27",X"0D",X"BD",X"E9",X"8A",X"97",X"C8",X"0F",X"C9",X"D7",X"CA",X"0F",X"CB",X"35",X"88", + X"04",X"EE",X"86",X"1F",X"97",X"EF",X"35",X"88",X"D6",X"EF",X"C1",X"E0",X"2F",X"0C",X"96",X"EF", + X"80",X"04",X"97",X"EF",X"4F",X"BD",X"E9",X"4A",X"35",X"88",X"0F",X"EF",X"0F",X"EE",X"BD",X"E8", + X"37",X"35",X"88",X"B6",X"C8",X"E7",X"27",X"2B",X"34",X"08",X"86",X"C8",X"1F",X"8B",X"96",X"E7", + X"27",X"21",X"DC",X"DE",X"D3",X"E2",X"DD",X"DE",X"97",X"DC",X"DC",X"E0",X"D3",X"E4",X"DD",X"E0", + X"97",X"DD",X"35",X"08",X"BD",X"F2",X"A5",X"C6",X"08",X"10",X"BE",X"C8",X"DC",X"8E",X"EF",X"B3", + X"BD",X"EA",X"7F",X"39",X"8E",X"E3",X"A1",X"9F",X"A3",X"BD",X"F5",X"17",X"8E",X"E4",X"48",X"84", + X"06",X"AE",X"86",X"EC",X"81",X"DD",X"DC",X"97",X"DE",X"0F",X"DF",X"D7",X"E0",X"0F",X"E1",X"20", + X"58",X"96",X"BF",X"26",X"19",X"BD",X"F5",X"17",X"84",X"7F",X"8B",X"30",X"97",X"A2",X"BD",X"F5", + X"17",X"84",X"3F",X"97",X"E6",X"BD",X"F5",X"17",X"8B",X"10",X"97",X"E7",X"20",X"49",X"96",X"BD", + X"26",X"E3",X"C6",X"1C",X"CE",X"C9",X"33",X"A6",X"C4",X"27",X"08",X"33",X"C8",X"12",X"5A",X"26", + X"F6",X"20",X"34",X"0C",X"ED",X"0A",X"BF",X"9E",X"DE",X"AF",X"44",X"9E",X"E0",X"AF",X"46",X"86", + X"40",X"A7",X"C4",X"96",X"C0",X"26",X"10",X"8E",X"E4",X"12",X"9F",X"9D",X"BD",X"F5",X"17",X"84", + X"7F",X"8B",X"40",X"97",X"9C",X"0C",X"C0",X"9E",X"E8",X"A6",X"80",X"97",X"A2",X"A6",X"80",X"97", + X"E6",X"A6",X"80",X"97",X"E7",X"9F",X"E8",X"D6",X"E6",X"BD",X"E7",X"B5",X"10",X"9F",X"E2",X"9F", + X"E4",X"39",X"CE",X"C8",X"C4",X"96",X"9B",X"EE",X"C6",X"A6",X"C4",X"C6",X"03",X"BD",X"E9",X"A1", + X"8E",X"E4",X"26",X"9F",X"9D",X"39",X"0A",X"C1",X"27",X"06",X"86",X"FF",X"97",X"9C",X"20",X"17", + X"BD",X"F5",X"17",X"1F",X"89",X"C4",X"03",X"26",X"02",X"CB",X"01",X"CE",X"C8",X"C4",X"96",X"9B", + X"EE",X"C6",X"A6",X"C4",X"BD",X"E9",X"A1",X"39",X"E4",X"50",X"E4",X"6A",X"E4",X"84",X"E4",X"9E", + X"7F",X"00",X"28",X"20",X"30",X"40",X"28",X"30",X"28",X"00",X"10",X"30",X"10",X"40",X"18",X"20", + X"50",X"40",X"30",X"28",X"30",X"08",X"60",X"7F",X"38",X"70",X"80",X"00",X"40",X"00",X"30",X"20", + X"10",X"50",X"20",X"28",X"40",X"30",X"3E",X"70",X"18",X"30",X"60",X"20",X"18",X"40",X"30",X"24", + X"50",X"7F",X"06",X"70",X"00",X"7F",X"40",X"10",X"60",X"28",X"38",X"30",X"28",X"08",X"40",X"30", + X"28",X"7F",X"20",X"18",X"30",X"30",X"08",X"68",X"40",X"20",X"50",X"7F",X"38",X"70",X"00",X"80", + X"40",X"30",X"60",X"38",X"18",X"30",X"30",X"20",X"18",X"20",X"38",X"40",X"28",X"10",X"60",X"20", + X"00",X"30",X"40",X"38",X"50",X"7F",X"1C",X"70",X"86",X"04",X"CE",X"C9",X"0B",X"8E",X"C8",X"15", + X"B7",X"C8",X"8F",X"BD",X"F2",X"A9",X"A6",X"C4",X"27",X"22",X"6A",X"49",X"27",X"19",X"EC",X"45", + X"E3",X"41",X"ED",X"45",X"EC",X"47",X"E3",X"43",X"ED",X"47",X"31",X"45",X"BD",X"EA",X"6D",X"33", + X"4A",X"7A",X"C8",X"8F",X"26",X"E0",X"39",X"6F",X"C4",X"7A",X"C8",X"EA",X"B6",X"C8",X"BD",X"26", + X"EE",X"B6",X"C8",X"EE",X"26",X"E9",X"A6",X"84",X"27",X"E5",X"6F",X"84",X"7C",X"C8",X"B6",X"6C", + X"C4",X"FC",X"C8",X"C8",X"ED",X"45",X"FC",X"C8",X"CA",X"ED",X"47",X"FC",X"C9",X"07",X"ED",X"41", + X"FC",X"C9",X"09",X"ED",X"43",X"86",X"18",X"A7",X"49",X"7C",X"C8",X"EA",X"20",X"C1",X"86",X"1C", + X"B7",X"C8",X"8F",X"CE",X"C9",X"33",X"A6",X"C4",X"26",X"09",X"33",X"C8",X"12",X"7A",X"C8",X"8F", + X"26",X"F4",X"39",X"10",X"2B",X"00",X"9C",X"85",X"40",X"10",X"26",X"00",X"A4",X"85",X"20",X"10", + X"26",X"00",X"A9",X"85",X"10",X"10",X"26",X"00",X"D4",X"85",X"01",X"10",X"26",X"00",X"D8",X"A6", + X"41",X"81",X"04",X"27",X"56",X"85",X"01",X"27",X"31",X"B6",X"C8",X"EE",X"26",X"2C",X"B6",X"C8", + X"BD",X"26",X"27",X"34",X"08",X"BD",X"F1",X"AF",X"96",X"C8",X"A0",X"44",X"D6",X"CA",X"E0",X"46", + X"BD",X"F5",X"93",X"80",X"10",X"97",X"83",X"8E",X"E2",X"3E",X"E6",X"43",X"A6",X"85",X"D6",X"83", + X"BD",X"E7",X"B5",X"10",X"AF",X"48",X"AF",X"4A",X"35",X"08",X"EC",X"44",X"E3",X"48",X"ED",X"44", + X"EC",X"46",X"E3",X"4A",X"ED",X"46",X"BD",X"F2",X"A5",X"8E",X"E2",X"5A",X"A6",X"41",X"48",X"AE", + X"86",X"31",X"44",X"E6",X"42",X"BD",X"EA",X"8D",X"7E",X"E5",X"2A",X"EC",X"44",X"E3",X"48",X"29", + X"1A",X"ED",X"44",X"EC",X"46",X"E3",X"4A",X"29",X"12",X"ED",X"46",X"BD",X"F2",X"A9",X"31",X"44", + X"8E",X"CB",X"A7",X"C6",X"04",X"BD",X"EA",X"8D",X"7E",X"E5",X"2A",X"6F",X"C4",X"7A",X"C8",X"EB", + X"7E",X"E5",X"2A",X"A6",X"46",X"AB",X"C8",X"10",X"A7",X"46",X"A1",X"C8",X"11",X"26",X"02",X"64", + X"C4",X"BD",X"F2",X"A5",X"31",X"44",X"BD",X"EA",X"6D",X"7E",X"E5",X"2A",X"A6",X"43",X"81",X"03", + X"26",X"0D",X"A6",X"42",X"A1",X"C8",X"10",X"2C",X"06",X"8B",X"08",X"A7",X"42",X"20",X"1B",X"64", + X"C4",X"A6",X"C8",X"10",X"A7",X"42",X"86",X"18",X"A7",X"C8",X"10",X"B6",X"C8",X"ED",X"26",X"0A", + X"B6",X"C8",X"C0",X"26",X"05",X"86",X"7F",X"B7",X"C8",X"A2",X"7E",X"E5",X"96",X"6A",X"C8",X"10", + X"26",X"02",X"64",X"C4",X"7E",X"E5",X"96",X"6F",X"C4",X"A6",X"41",X"81",X"04",X"27",X"15",X"E6", + X"43",X"5A",X"27",X"10",X"34",X"0A",X"86",X"C8",X"1F",X"8B",X"A6",X"E4",X"BD",X"E9",X"A1",X"BD", + X"E9",X"A1",X"35",X"0A",X"7E",X"E5",X"2A",X"34",X"08",X"BD",X"F1",X"AA",X"BD",X"F2",X"A9",X"CE", + X"CB",X"2B",X"86",X"0E",X"B7",X"C8",X"8F",X"A6",X"C4",X"10",X"27",X"00",X"A6",X"E6",X"44",X"E1", + X"41",X"24",X"0D",X"CB",X"03",X"E7",X"44",X"10",X"AE",X"42",X"8E",X"EE",X"BA",X"BD",X"EA",X"7F", + X"4D",X"10",X"2A",X"00",X"83",X"7A",X"C8",X"F7",X"10",X"27",X"00",X"37",X"B6",X"C8",X"26",X"84", + X"01",X"26",X"03",X"7C",X"C8",X"F8",X"B6",X"C8",X"F8",X"10",X"8E",X"7F",X"00",X"8E",X"EF",X"04", + X"BD",X"E7",X"6A",X"10",X"8E",X"60",X"80",X"8E",X"EF",X"0B",X"BD",X"E7",X"6A",X"10",X"8E",X"80", + X"50",X"8E",X"EF",X"15",X"BD",X"E7",X"6A",X"10",X"8E",X"A0",X"80",X"8E",X"EF",X"1C",X"BD",X"E7", + X"6A",X"20",X"50",X"7A",X"C8",X"D9",X"7F",X"C8",X"EB",X"7F",X"C8",X"ED",X"B6",X"C8",X"79",X"27", + X"2B",X"B6",X"C8",X"9B",X"44",X"8E",X"C8",X"DA",X"F6",X"C8",X"D9",X"E7",X"86",X"B6",X"C8",X"DA", + X"26",X"05",X"B6",X"C8",X"DB",X"27",X"1A",X"B6",X"C8",X"9B",X"8B",X"02",X"84",X"02",X"B7",X"C8", + X"9B",X"44",X"8E",X"C8",X"DA",X"E6",X"86",X"F7",X"C8",X"D9",X"27",X"EB",X"B6",X"C8",X"D9",X"26", + X"0D",X"86",X"01",X"B7",X"C8",X"BE",X"20",X"06",X"E6",X"44",X"E1",X"41",X"25",X"05",X"6F",X"C4", + X"7A",X"C8",X"EC",X"33",X"45",X"7A",X"C8",X"8F",X"10",X"26",X"FF",X"4B",X"BD",X"EC",X"C9",X"20", + X"05",X"34",X"08",X"BD",X"F1",X"AA",X"BD",X"F2",X"A5",X"8E",X"80",X"38",X"BF",X"C8",X"90",X"B6", + X"C8",X"D9",X"27",X"1E",X"B7",X"C8",X"8F",X"7A",X"C8",X"8F",X"27",X"16",X"B6",X"C8",X"91",X"8B", + X"06",X"B7",X"C8",X"91",X"C6",X"04",X"10",X"BE",X"C8",X"90",X"8E",X"EE",X"EB",X"BD",X"EA",X"7F", + X"20",X"E5",X"35",X"08",X"96",X"26",X"84",X"01",X"48",X"48",X"48",X"8E",X"EE",X"AD",X"CE",X"CB", + X"A7",X"BD",X"F6",X"1F",X"D6",X"EC",X"26",X"0F",X"96",X"BD",X"26",X"08",X"D6",X"EB",X"26",X"07", + X"D6",X"ED",X"26",X"03",X"1C",X"FE",X"39",X"1A",X"01",X"39",X"34",X"32",X"8E",X"C8",X"C8",X"BD", + X"F2",X"F2",X"A6",X"E4",X"97",X"04",X"1F",X"20",X"BD",X"F3",X"12",X"C6",X"0C",X"AE",X"61",X"BD", + X"F4",X"0E",X"35",X"B2",X"34",X"16",X"8E",X"CB",X"2B",X"86",X"0E",X"E6",X"84",X"27",X"07",X"30", + X"05",X"4A",X"26",X"F7",X"20",X"1D",X"A6",X"E4",X"84",X"80",X"4C",X"A7",X"84",X"2A",X"02",X"0C", + X"BD",X"A6",X"E4",X"84",X"7F",X"A7",X"04",X"A6",X"61",X"A7",X"01",X"EC",X"62",X"ED",X"02",X"0C", + X"EC",X"0C",X"F3",X"35",X"96",X"34",X"36",X"BD",X"F6",X"01",X"A7",X"64",X"1D",X"58",X"49",X"58", + X"49",X"58",X"49",X"ED",X"62",X"E6",X"64",X"1D",X"58",X"49",X"58",X"49",X"58",X"49",X"ED",X"64", + X"35",X"B6",X"34",X"36",X"8D",X"DF",X"EC",X"7C",X"58",X"49",X"ED",X"64",X"EC",X"7A",X"58",X"49", + X"ED",X"62",X"35",X"B6",X"86",X"D0",X"1F",X"8B",X"BD",X"F2",X"72",X"86",X"C8",X"1F",X"8B",X"0F", + X"9C",X"0F",X"9F",X"0F",X"A2",X"0F",X"A5",X"8E",X"C9",X"0B",X"6F",X"80",X"8C",X"CB",X"71",X"26", + X"F9",X"CC",X"00",X"00",X"DD",X"DE",X"DD",X"E0",X"DD",X"E2",X"DD",X"E4",X"97",X"E7",X"97",X"BD", + X"97",X"BE",X"97",X"EA",X"97",X"EB",X"97",X"EC",X"97",X"F8",X"C6",X"40",X"D7",X"F7",X"97",X"ED", + X"97",X"C0",X"8E",X"08",X"00",X"9F",X"F0",X"86",X"07",X"97",X"BF",X"8E",X"E3",X"84",X"9F",X"A3", + X"CC",X"00",X"00",X"DD",X"C8",X"DD",X"CA",X"CC",X"00",X"00",X"97",X"D4",X"DD",X"CC",X"DD",X"CE", + X"97",X"D5",X"97",X"D6",X"DD",X"D0",X"DD",X"D2",X"97",X"D7",X"97",X"D8",X"96",X"D4",X"8E",X"EE", + X"EB",X"CE",X"CB",X"89",X"BD",X"F6",X"1F",X"86",X"7F",X"D6",X"D4",X"BD",X"E7",X"D2",X"10",X"BF", + X"C9",X"07",X"BF",X"C9",X"09",X"39",X"34",X"30",X"34",X"08",X"BD",X"F1",X"AA",X"BD",X"F2",X"72", + X"35",X"08",X"86",X"A0",X"97",X"8F",X"96",X"C8",X"27",X"0A",X"2B",X"03",X"4A",X"20",X"01",X"4C", + X"97",X"C8",X"0F",X"C9",X"96",X"CA",X"27",X"0A",X"2B",X"03",X"4A",X"20",X"01",X"4C",X"97",X"CA", + X"0F",X"CB",X"96",X"D4",X"27",X"0C",X"81",X"1F",X"2E",X"03",X"4A",X"20",X"01",X"4C",X"84",X"3F", + X"97",X"D4",X"BD",X"E2",X"F2",X"8E",X"CB",X"81",X"C6",X"08",X"A6",X"84",X"8B",X"03",X"A7",X"80", + X"5A",X"26",X"F7",X"34",X"08",X"BD",X"F1",X"AA",X"BD",X"EA",X"CF",X"5F",X"86",X"20",X"BD",X"E9", + X"0B",X"BD",X"E8",X"FD",X"35",X"08",X"96",X"C8",X"10",X"26",X"FF",X"AA",X"96",X"CA",X"10",X"26", + X"FF",X"A4",X"96",X"D4",X"10",X"26",X"FF",X"9E",X"0A",X"8F",X"10",X"26",X"FF",X"98",X"BD",X"E7", + X"E4",X"35",X"B0",X"8E",X"ED",X"E0",X"10",X"8E",X"CB",X"71",X"CE",X"CB",X"81",X"C6",X"08",X"86", + X"16",X"AF",X"A1",X"30",X"08",X"A7",X"C0",X"8B",X"0F",X"5A",X"26",X"F5",X"39",X"34",X"1E",X"8E", + X"CB",X"81",X"86",X"08",X"6C",X"80",X"4A",X"26",X"FB",X"20",X"02",X"34",X"1E",X"86",X"D0",X"1F", + X"8B",X"86",X"09",X"34",X"02",X"6A",X"E4",X"26",X"07",X"BD",X"F3",X"54",X"35",X"02",X"35",X"9E", + X"BD",X"F3",X"54",X"86",X"03",X"B7",X"C8",X"23",X"A6",X"E4",X"4A",X"8E",X"CB",X"81",X"E6",X"86", + X"C4",X"7F",X"E1",X"61",X"23",X"DF",X"E0",X"62",X"2F",X"DB",X"D7",X"04",X"8E",X"CB",X"71",X"48", + X"AE",X"86",X"BD",X"F2",X"A9",X"BD",X"F2",X"D5",X"20",X"CB",X"34",X"1E",X"86",X"D0",X"1F",X"8B", + X"86",X"09",X"34",X"02",X"6A",X"E4",X"26",X"07",X"BD",X"F3",X"54",X"35",X"02",X"35",X"9E",X"BD", + X"F3",X"54",X"86",X"03",X"B7",X"C8",X"23",X"8E",X"C8",X"C8",X"BD",X"F2",X"F2",X"E6",X"E4",X"58", + X"58",X"EB",X"62",X"2F",X"DF",X"C4",X"7F",X"D7",X"04",X"8E",X"CB",X"71",X"A6",X"E4",X"4A",X"48", + X"AE",X"86",X"BD",X"F2",X"A9",X"BD",X"F2",X"D5",X"20",X"CA",X"34",X"06",X"BD",X"F5",X"17",X"A7", + X"E4",X"BD",X"F5",X"17",X"81",X"60",X"2E",X"F9",X"81",X"A0",X"2D",X"F5",X"A7",X"61",X"35",X"06", + X"39",X"34",X"76",X"96",X"ED",X"10",X"27",X"00",X"93",X"0A",X"ED",X"BD",X"F5",X"17",X"84",X"1F", + X"97",X"8B",X"81",X"1B",X"23",X"04",X"80",X"04",X"20",X"F6",X"C6",X"12",X"3D",X"C3",X"C9",X"33", + X"1F",X"03",X"A6",X"C4",X"84",X"C0",X"26",X"0D",X"0C",X"8B",X"96",X"8B",X"81",X"1B",X"2F",X"EA", + X"0F",X"8B",X"4F",X"20",X"E5",X"A6",X"E4",X"A7",X"41",X"8E",X"E2",X"42",X"48",X"10",X"AE",X"86", + X"10",X"9F",X"89",X"C6",X"20",X"E7",X"C4",X"8E",X"E2",X"3E",X"A6",X"61",X"E6",X"86",X"D7",X"8B", + X"8E",X"E2",X"3A",X"E6",X"86",X"E7",X"C8",X"10",X"A7",X"43",X"8E",X"E2",X"52",X"48",X"10",X"AE", + X"86",X"10",X"AF",X"4C",X"8E",X"E2",X"4A",X"10",X"AE",X"86",X"10",X"9F",X"87",X"81",X"06",X"26", + X"02",X"0C",X"F4",X"96",X"88",X"9B",X"8A",X"19",X"A7",X"4F",X"96",X"87",X"99",X"89",X"19",X"A7", + X"4E",X"96",X"8B",X"BD",X"EA",X"3E",X"BD",X"E7",X"B5",X"10",X"AF",X"48",X"AF",X"4A",X"0C",X"EB", + X"96",X"C0",X"27",X"08",X"86",X"FF",X"97",X"9C",X"86",X"03",X"97",X"C1",X"35",X"F6",X"34",X"06", + X"BD",X"F5",X"17",X"1F",X"89",X"84",X"30",X"A7",X"61",X"C4",X"0F",X"C1",X"04",X"24",X"02",X"CB", + X"04",X"C1",X"0C",X"23",X"02",X"C0",X"04",X"EB",X"61",X"E7",X"61",X"35",X"86",X"34",X"06",X"86", + X"7F",X"97",X"04",X"1F",X"20",X"BD",X"F2",X"C3",X"BD",X"F3",X"54",X"35",X"86",X"34",X"06",X"86", + X"7F",X"97",X"04",X"A6",X"A4",X"E6",X"22",X"BD",X"F2",X"C3",X"BD",X"F3",X"54",X"35",X"86",X"34", + X"16",X"1F",X"20",X"BD",X"F2",X"FC",X"E6",X"61",X"BD",X"F4",X"0E",X"35",X"96",X"34",X"16",X"1F", + X"21",X"BD",X"F2",X"F2",X"E6",X"61",X"AE",X"62",X"BD",X"F4",X"0E",X"35",X"96",X"34",X"56",X"86", + X"7F",X"97",X"04",X"BD",X"F3",X"73",X"35",X"D6",X"34",X"56",X"1F",X"20",X"BD",X"F2",X"FC",X"BD", + X"F4",X"95",X"35",X"B6",X"BD",X"F2",X"A9",X"CC",X"FC",X"38",X"FD",X"C8",X"2A",X"B6",X"C8",X"9B", + X"10",X"8E",X"ED",X"A3",X"10",X"AE",X"A6",X"CE",X"ED",X"9F",X"EE",X"C6",X"8D",X"DA",X"39",X"BD", + X"F2",X"A9",X"CC",X"FC",X"38",X"FD",X"C8",X"2A",X"10",X"8E",X"7F",X"A0",X"CE",X"C8",X"A8",X"8D", + X"C7",X"B6",X"C8",X"79",X"27",X"09",X"10",X"8E",X"7F",X"10",X"CE",X"C8",X"AF",X"8D",X"B9",X"39", + X"BD",X"F1",X"92",X"34",X"08",X"BD",X"F2",X"E6",X"BD",X"EA",X"B4",X"B6",X"C8",X"80",X"BD",X"F1", + X"B4",X"FC",X"C8",X"81",X"FD",X"C8",X"1F",X"FD",X"C8",X"21",X"BD",X"F1",X"F8",X"86",X"C8",X"1F", + X"8B",X"96",X"9C",X"27",X"08",X"0A",X"9C",X"26",X"04",X"AD",X"9F",X"C8",X"9D",X"96",X"9F",X"27", + X"08",X"0A",X"9F",X"26",X"04",X"AD",X"9F",X"C8",X"A0",X"96",X"A2",X"27",X"08",X"0A",X"A2",X"26", + X"04",X"AD",X"9F",X"C8",X"A3",X"96",X"A5",X"27",X"08",X"0A",X"A5",X"26",X"04",X"AD",X"9F",X"C8", + X"A6",X"35",X"88",X"96",X"EA",X"27",X"12",X"10",X"8E",X"C9",X"0B",X"86",X"04",X"97",X"8F",X"6D", + X"A4",X"26",X"07",X"31",X"2A",X"0A",X"8F",X"26",X"F6",X"39",X"96",X"E7",X"27",X"35",X"34",X"20", + X"A6",X"25",X"E6",X"27",X"1F",X"01",X"CC",X"06",X"16",X"10",X"9E",X"DC",X"BD",X"F8",X"FF",X"35", + X"20",X"24",X"20",X"6F",X"A4",X"0F",X"E7",X"0F",X"A2",X"8E",X"ED",X"9F",X"96",X"9B",X"AE",X"86", + X"CC",X"10",X"00",X"BD",X"F8",X"7C",X"86",X"30",X"C6",X"70",X"9E",X"DC",X"BD",X"E7",X"84",X"0A", + X"EA",X"20",X"C6",X"CE",X"C9",X"33",X"86",X"1C",X"97",X"90",X"A6",X"C4",X"84",X"3F",X"26",X"09", + X"33",X"C8",X"12",X"0A",X"90",X"26",X"F3",X"20",X"AA",X"34",X"20",X"A6",X"25",X"E6",X"27",X"1F", + X"01",X"A6",X"44",X"E6",X"46",X"1F",X"02",X"EC",X"4C",X"BD",X"F8",X"FF",X"35",X"20",X"24",X"E0", + X"A6",X"41",X"84",X"02",X"27",X"5A",X"8E",X"ED",X"9F",X"96",X"9B",X"AE",X"86",X"EC",X"4E",X"BD", + X"F8",X"7C",X"0C",X"F5",X"A6",X"44",X"E6",X"46",X"1F",X"01",X"A6",X"42",X"C6",X"20",X"BD",X"E7", + X"84",X"CC",X"01",X"10",X"ED",X"4E",X"96",X"C8",X"A0",X"44",X"D6",X"CA",X"E0",X"46",X"BD",X"F5", + X"93",X"80",X"10",X"1F",X"89",X"34",X"20",X"86",X"3F",X"BD",X"E7",X"B5",X"10",X"AF",X"48",X"AF", + X"4A",X"35",X"20",X"6F",X"A4",X"CC",X"04",X"04",X"ED",X"4C",X"A6",X"41",X"E6",X"43",X"5A",X"27", + X"06",X"BD",X"E9",X"A1",X"BD",X"E9",X"A1",X"86",X"04",X"A7",X"41",X"0A",X"EA",X"7E",X"EB",X"53", + X"86",X"01",X"A7",X"C4",X"6F",X"A4",X"8E",X"ED",X"9F",X"96",X"9B",X"AE",X"86",X"EC",X"4E",X"BD", + X"F8",X"7C",X"A6",X"44",X"E6",X"46",X"1F",X"01",X"A6",X"42",X"C6",X"40",X"BD",X"E7",X"84",X"0A", + X"EB",X"0A",X"EA",X"7E",X"EB",X"53",X"96",X"BD",X"26",X"19",X"96",X"EE",X"26",X"15",X"10",X"8E", + X"C9",X"33",X"86",X"1C",X"97",X"8F",X"A6",X"A4",X"84",X"3F",X"26",X"08",X"31",X"A8",X"12",X"0A", + X"8F",X"26",X"F3",X"39",X"34",X"20",X"96",X"C8",X"D6",X"CA",X"1F",X"01",X"A6",X"24",X"E6",X"26", + X"10",X"AE",X"2C",X"1E",X"20",X"BD",X"F8",X"FF",X"35",X"20",X"24",X"E0",X"6F",X"A4",X"0F",X"ED", + X"96",X"C8",X"D6",X"CA",X"1F",X"01",X"A6",X"22",X"8A",X"80",X"C6",X"30",X"BD",X"E7",X"84",X"0C", + X"F3",X"0A",X"EB",X"20",X"CE",X"96",X"BD",X"26",X"19",X"96",X"EE",X"26",X"15",X"96",X"E7",X"27", + X"11",X"96",X"C8",X"D6",X"CA",X"1F",X"01",X"CC",X"06",X"16",X"10",X"9E",X"DC",X"BD",X"F8",X"FF", + X"25",X"01",X"39",X"0F",X"E7",X"0F",X"A2",X"96",X"C8",X"D6",X"CA",X"1F",X"01",X"86",X"08",X"8A", + X"80",X"C6",X"30",X"BD",X"E7",X"84",X"0C",X"F3",X"39",X"B6",X"C8",X"F2",X"27",X"08",X"7F",X"C8", + X"F2",X"CE",X"ED",X"37",X"20",X"31",X"B6",X"C8",X"F3",X"27",X"08",X"7F",X"C8",X"F3",X"CE",X"ED", + X"4D",X"20",X"24",X"B6",X"C8",X"B6",X"27",X"08",X"7F",X"C8",X"B6",X"CE",X"ED",X"42",X"20",X"17", + X"B6",X"C8",X"F4",X"27",X"0B",X"7F",X"C8",X"F4",X"7F",X"C8",X"F6",X"CE",X"ED",X"5A",X"20",X"07", + X"B6",X"C8",X"F6",X"26",X"F0",X"20",X"03",X"BD",X"F2",X"7D",X"F6",X"C8",X"00",X"CB",X"10",X"C1", + X"A0",X"24",X"07",X"86",X"00",X"BD",X"F2",X"56",X"20",X"06",X"CC",X"08",X"00",X"BD",X"F2",X"56", + X"F6",X"C8",X"02",X"CB",X"20",X"C1",X"F0",X"24",X"07",X"86",X"02",X"BD",X"F2",X"56",X"20",X"06", + X"CC",X"09",X"00",X"BD",X"F2",X"56",X"39",X"00",X"10",X"01",X"00",X"06",X"1F",X"07",X"06",X"08", + X"0F",X"FF",X"02",X"39",X"03",X"00",X"06",X"1F",X"07",X"05",X"09",X"0F",X"FF",X"06",X"1F",X"07", + X"07",X"0A",X"10",X"0B",X"00",X"0C",X"38",X"0D",X"00",X"FF",X"00",X"00",X"01",X"00",X"02",X"30", + X"03",X"00",X"04",X"00",X"05",X"00",X"06",X"1F",X"07",X"3D",X"08",X"00",X"09",X"0F",X"0A",X"00", + X"0B",X"00",X"0C",X"00",X"0D",X"00",X"FF",X"ED",X"8F",X"FE",X"B6",X"00",X"19",X"01",X"19",X"00", + X"19",X"01",X"32",X"00",X"19",X"01",X"19",X"00",X"19",X"06",X"19",X"05",X"19",X"00",X"80",X"FF", + X"EE",X"DD",X"CC",X"BB",X"AA",X"99",X"88",X"77",X"77",X"77",X"77",X"77",X"77",X"77",X"77",X"C8", + X"A8",X"C8",X"AF",X"7F",X"A0",X"7F",X"10",X"C8",X"F9",X"C9",X"00",X"00",X"00",X"00",X"00",X"02", + X"00",X"00",X"00",X"01",X"00",X"00",X"00",X"03",X"00",X"00",X"00",X"02",X"01",X"00",X"00",X"02", + X"03",X"00",X"00",X"01",X"03",X"00",X"00",X"02",X"02",X"00",X"00",X"01",X"01",X"00",X"00",X"03", + X"03",X"00",X"00",X"02",X"02",X"02",X"00",X"01",X"01",X"01",X"00",X"03",X"03",X"03",X"00",X"80", + X"C8",X"40",X"3F",X"00",X"20",X"80",X"10",X"1F",X"3F",X"3F",X"00",X"BF",X"BF",X"BF",X"C0",X"20", + X"48",X"08",X"F8",X"30",X"A8",X"10",X"D0",X"A0",X"BF",X"BF",X"00",X"3F",X"3F",X"48",X"20",X"80", + X"00",X"B0",X"48",X"38",X"FB",X"38",X"80",X"28",X"30",X"48",X"80",X"80",X"45",X"F0",X"28",X"7F", + X"3F",X"BF",X"A5",X"00",X"D0",X"60",X"20",X"28",X"B8",X"40",X"15",X"80",X"40",X"F8",X"40",X"18", + X"FA",X"38",X"E0",X"C8",X"4D",X"49",X"4E",X"45",X"20",X"46",X"49",X"45",X"4C",X"44",X"80",X"FA", + X"38",X"E0",X"D8",X"47",X"41",X"4D",X"45",X"20",X"4F",X"56",X"45",X"52",X"80",X"00",X"10",X"00", + X"FF",X"20",X"A0",X"FF",X"C0",X"40",X"FF",X"90",X"20",X"FF",X"70",X"20",X"FF",X"50",X"50",X"FF", + X"D0",X"90",X"01",X"00",X"20",X"00",X"FF",X"30",X"B0",X"FF",X"B0",X"30",X"FF",X"B0",X"D0",X"FF", + X"30",X"50",X"FF",X"D0",X"50",X"FF",X"50",X"D0",X"FF",X"50",X"30",X"FF",X"D0",X"B0",X"01",X"FF", + X"00",X"00",X"00",X"30",X"00",X"FF",X"10",X"C0",X"FF",X"C0",X"10",X"FF",X"C0",X"F0",X"FF",X"10", + X"40",X"FF",X"F0",X"40",X"FF",X"40",X"F0",X"FF",X"40",X"10",X"FF",X"F0",X"C0",X"01",X"FF",X"00", + X"00",X"00",X"F0",X"D0",X"FF",X"C0",X"40",X"FF",X"20",X"00",X"FF",X"40",X"40",X"FF",X"00",X"E0", + X"FF",X"40",X"C0",X"FF",X"E0",X"00",X"FF",X"C0",X"C0",X"FF",X"00",X"20",X"01",X"00",X"3F",X"00", + X"FF",X"80",X"00",X"00",X"3F",X"3F",X"FF",X"00",X"80",X"01",X"FF",X"7F",X"20",X"00",X"C0",X"10", + X"FF",X"C0",X"D0",X"FF",X"20",X"7F",X"00",X"E0",X"C0",X"FF",X"00",X"C0",X"FF",X"E0",X"30",X"00", + X"C0",X"00",X"FF",X"60",X"CD",X"FF",X"A0",X"00",X"00",X"20",X"D0",X"FF",X"3C",X"30",X"FF",X"00", + X"82",X"00",X"30",X"30",X"FF",X"D0",X"50",X"FF",X"20",X"F0",X"01",X"00",X"3F",X"00",X"FF",X"C4", + X"08",X"FF",X"D8",X"D8",X"FF",X"20",X"00",X"00",X"00",X"40",X"FF",X"E0",X"00",X"FF",X"28",X"D8", + X"FF",X"3C",X"08",X"01",X"00",X"3F",X"00",X"FF",X"C4",X"08",X"01",X"00",X"04",X"08",X"FF",X"D8", + X"D8",X"FF",X"20",X"00",X"01",X"00",X"3F",X"00",X"FF",X"C4",X"F8",X"01",X"00",X"04",X"F8",X"FF", + X"D8",X"28",X"FF",X"20",X"00",X"01",X"00",X"20",X"00",X"FF",X"00",X"D8",X"FF",X"D0",X"A8",X"FF", + X"F0",X"40",X"FF",X"08",X"18",X"FF",X"18",X"F0",X"FF",X"F0",X"B8",X"00",X"10",X"48",X"FF",X"08", + X"00",X"FF",X"E8",X"10",X"FF",X"F8",X"00",X"00",X"08",X"00",X"FF",X"00",X"06",X"00",X"10",X"FA", + X"FF",X"08",X"00",X"FF",X"00",X"F0",X"00",X"10",X"18",X"FF",X"F0",X"08",X"01",X"00",X"20",X"00", + X"FF",X"00",X"28",X"FF",X"D0",X"58",X"FF",X"F0",X"C0",X"FF",X"08",X"E8",X"FF",X"18",X"10",X"FF", + X"F0",X"48",X"00",X"10",X"B8",X"FF",X"08",X"00",X"FF",X"E8",X"F0",X"FF",X"F8",X"00",X"FF",X"08", + X"00",X"FF",X"00",X"FA",X"00",X"10",X"06",X"FF",X"08",X"00",X"FF",X"00",X"10",X"00",X"10",X"E8", + X"FF",X"F0",X"F8",X"01",X"FF",X"00",X"D8",X"FF",X"E8",X"08",X"FF",X"00",X"40",X"FF",X"18",X"08", + X"FF",X"00",X"D8",X"00",X"08",X"E0",X"FF",X"10",X"00",X"FF",X"00",X"40",X"FF",X"F0",X"00",X"FF", + X"00",X"C0",X"01",X"00",X"18",X"00",X"FF",X"00",X"20",X"FF",X"C8",X"70",X"FF",X"10",X"A0",X"FF", + X"00",X"A0",X"FF",X"EC",X"A4",X"FF",X"39",X"6D",X"FF",X"00",X"20",X"01",X"00",X"00",X"00",X"00", + X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00", + X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00", + X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00", + X"10",X"CE",X"CB",X"EA",X"BD",X"F1",X"8B",X"CC",X"73",X"21",X"10",X"B3",X"CB",X"FE",X"27",X"5C", + X"FD",X"CB",X"FE",X"7C",X"C8",X"3B",X"8E",X"CB",X"EB",X"BD",X"F8",X"4F",X"BD",X"F1",X"AF",X"DC", + X"25",X"10",X"83",X"01",X"01",X"26",X"02",X"D7",X"56",X"57",X"C4",X"03",X"8E",X"F0",X"FD",X"E6", + X"85",X"D7",X"29",X"C6",X"02",X"D7",X"24",X"CE",X"FD",X"0D",X"BD",X"F6",X"87",X"BD",X"F1",X"92", + X"BD",X"F2",X"89",X"BD",X"F2",X"A9",X"B6",X"C8",X"26",X"CE",X"F1",X"0C",X"85",X"20",X"27",X"02", + X"33",X"4C",X"BD",X"F3",X"85",X"8E",X"F0",X"E9",X"BD",X"F3",X"08",X"86",X"03",X"BD",X"F4",X"34", + X"7A",X"C8",X"24",X"26",X"F3",X"B6",X"C8",X"25",X"81",X"01",X"23",X"B0",X"BD",X"F1",X"AF",X"86", + X"CC",X"97",X"29",X"CC",X"F1",X"01",X"DD",X"39",X"0F",X"25",X"0F",X"26",X"CE",X"00",X"00",X"8E", + X"F1",X"01",X"C6",X"0B",X"A6",X"C0",X"A1",X"80",X"27",X"0D",X"C1",X"01",X"27",X"04",X"C1",X"05", + X"23",X"05",X"CE",X"E0",X"00",X"20",X"07",X"5A",X"26",X"EA",X"D7",X"39",X"D7",X"3A",X"0C",X"56", + X"DF",X"37",X"EE",X"C4",X"BD",X"F1",X"AF",X"CC",X"F8",X"48",X"DD",X"2A",X"BD",X"F6",X"87",X"BD", + X"F1",X"92",X"BD",X"F2",X"89",X"BD",X"F2",X"A9",X"CC",X"C0",X"C0",X"FE",X"C8",X"39",X"BD",X"F3", + X"7A",X"B6",X"C8",X"3B",X"26",X"0C",X"4A",X"CE",X"CB",X"EB",X"A7",X"46",X"CC",X"68",X"D0",X"BD", + X"F3",X"7A",X"FE",X"C8",X"37",X"33",X"42",X"BD",X"F3",X"85",X"B6",X"C8",X"56",X"26",X"C5",X"BE", + X"C8",X"25",X"8C",X"00",X"7D",X"23",X"BD",X"6E",X"41",X"40",X"D6",X"00",X"56",X"81",X"00",X"00", + X"A9",X"7E",X"00",X"39",X"DC",X"8E",X"00",X"00",X"4A",X"72",X"00",X"00",X"B6",X"E0",X"38",X"0E", + X"03",X"67",X"20",X"47",X"43",X"45",X"20",X"31",X"39",X"38",X"32",X"80",X"F1",X"60",X"27",X"CF", + X"56",X"45",X"43",X"54",X"52",X"45",X"58",X"80",X"F3",X"60",X"26",X"CF",X"56",X"45",X"43",X"54", + X"52",X"45",X"58",X"80",X"FC",X"60",X"DF",X"E9",X"47",X"43",X"45",X"80",X"FC",X"38",X"CC",X"D1", + X"45",X"4E",X"54",X"45",X"52",X"54",X"41",X"49",X"4E",X"49",X"4E",X"47",X"80",X"FC",X"38",X"BC", + X"DC",X"4E",X"45",X"57",X"20",X"49",X"44",X"45",X"41",X"53",X"80",X"00",X"8D",X"5C",X"CC",X"9F", + X"FF",X"DD",X"02",X"CC",X"01",X"00",X"DD",X"00",X"CC",X"98",X"7F",X"97",X"0B",X"D7",X"04",X"BD", + X"F3",X"54",X"20",X"3E",X"8D",X"49",X"C6",X"7A",X"8E",X"C8",X"00",X"BD",X"F5",X"3F",X"CC",X"C8", + X"7D",X"DD",X"7B",X"0C",X"7D",X"27",X"FC",X"86",X"05",X"97",X"28",X"CC",X"30",X"75",X"DD",X"3D", + X"CC",X"01",X"03",X"DD",X"1F",X"CC",X"05",X"07",X"DD",X"21",X"39",X"8D",X"D7",X"8D",X"BD",X"7E", + X"F2",X"72",X"BE",X"C8",X"25",X"30",X"01",X"BF",X"C8",X"25",X"8D",X"0E",X"86",X"20",X"95",X"0D", + X"27",X"FC",X"FC",X"C8",X"3D",X"DD",X"08",X"7E",X"F2",X"E6",X"86",X"D0",X"1F",X"8B",X"39",X"86", + X"C8",X"1F",X"8B",X"39",X"B4",X"C8",X"0F",X"B7",X"C8",X"0F",X"8E",X"C8",X"12",X"A6",X"1D",X"A7", + X"1E",X"86",X"0E",X"97",X"01",X"CC",X"19",X"01",X"97",X"00",X"12",X"D7",X"00",X"0F",X"03",X"CC", + X"09",X"01",X"97",X"00",X"12",X"96",X"01",X"43",X"A7",X"1D",X"D7",X"00",X"C6",X"FF",X"D7",X"03", + X"43",X"AA",X"1E",X"43",X"A7",X"1F",X"34",X"02",X"C6",X"01",X"1F",X"98",X"A4",X"E4",X"A7",X"80", + X"58",X"26",X"F7",X"35",X"82",X"7A",X"C8",X"23",X"8E",X"C8",X"1F",X"A6",X"80",X"26",X"0C",X"8C", + X"C8",X"23",X"26",X"F7",X"6F",X"84",X"86",X"01",X"97",X"00",X"39",X"97",X"00",X"0F",X"01",X"0A", + X"00",X"C6",X"60",X"5C",X"2A",X"FD",X"B6",X"C8",X"23",X"2B",X"25",X"86",X"20",X"0C",X"00",X"95", + X"00",X"27",X"0A",X"C6",X"40",X"D7",X"01",X"95",X"00",X"26",X"0B",X"20",X"08",X"C6",X"C0",X"D7", + X"01",X"95",X"00",X"27",X"01",X"5F",X"E7",X"1B",X"20",X"C5",X"1F",X"98",X"9A",X"01",X"97",X"01", + X"86",X"20",X"95",X"00",X"26",X"06",X"1F",X"98",X"98",X"01",X"97",X"01",X"54",X"F1",X"C8",X"1A", + X"26",X"E8",X"D6",X"01",X"20",X"E0",X"8E",X"C8",X"00",X"E7",X"86",X"97",X"01",X"86",X"19",X"97", + X"00",X"86",X"01",X"97",X"00",X"96",X"01",X"D7",X"01",X"C6",X"11",X"D7",X"00",X"C6",X"01",X"D7", + X"00",X"39",X"CC",X"0E",X"00",X"8D",X"DF",X"4A",X"2A",X"FB",X"7E",X"F5",X"33",X"8E",X"C8",X"00", + X"20",X"02",X"8D",X"D5",X"EC",X"C1",X"2A",X"FA",X"39",X"8E",X"C8",X"00",X"CE",X"C8",X"3F",X"86", + X"0D",X"E6",X"C0",X"E1",X"86",X"27",X"02",X"8D",X"C0",X"4A",X"2A",X"F5",X"39",X"86",X"1F",X"20", + X"0A",X"86",X"3F",X"20",X"06",X"86",X"5F",X"20",X"02",X"86",X"7F",X"97",X"01",X"B7",X"C8",X"27", + X"CC",X"05",X"04",X"97",X"00",X"D7",X"00",X"D7",X"00",X"C6",X"01",X"D7",X"00",X"39",X"F7",X"C8", + X"28",X"EC",X"81",X"8D",X"4D",X"86",X"FF",X"97",X"0A",X"F6",X"C8",X"28",X"5A",X"26",X"FD",X"0F", + X"0A",X"39",X"7A",X"C8",X"23",X"8D",X"EA",X"B6",X"C8",X"23",X"26",X"F6",X"20",X"76",X"A6",X"80", + X"2E",X"72",X"8D",X"DD",X"20",X"F8",X"8E",X"F9",X"F0",X"8D",X"1D",X"BD",X"F3",X"6B",X"8D",X"20", + X"20",X"62",X"C6",X"7F",X"D7",X"04",X"A6",X"84",X"E6",X"02",X"20",X"16",X"97",X"01",X"34",X"06", + X"86",X"7F",X"97",X"04",X"0F",X"00",X"20",X"10",X"C6",X"FF",X"20",X"02",X"C6",X"7F",X"D7",X"04", + X"EC",X"81",X"97",X"01",X"0F",X"00",X"34",X"06",X"86",X"CE",X"97",X"0C",X"0F",X"0A",X"0C",X"00", + X"D7",X"01",X"0F",X"05",X"35",X"06",X"BD",X"F5",X"84",X"E7",X"7F",X"AA",X"7F",X"C6",X"40",X"81", + X"40",X"23",X"12",X"81",X"64",X"23",X"04",X"86",X"08",X"20",X"02",X"86",X"04",X"D5",X"0D",X"27", + X"FC",X"4A",X"26",X"FD",X"39",X"D5",X"0D",X"27",X"FC",X"39",X"BD",X"F1",X"AA",X"20",X"05",X"B6", + X"C8",X"24",X"27",X"16",X"CC",X"00",X"CC",X"D7",X"0C",X"97",X"0A",X"CC",X"03",X"02",X"0F",X"01", + X"97",X"00",X"D7",X"00",X"D7",X"00",X"C6",X"01",X"D7",X"00",X"39",X"CC",X"00",X"CC",X"D7",X"0C", + X"97",X"0A",X"39",X"EC",X"C1",X"FD",X"C8",X"2A",X"EC",X"C1",X"BD",X"F2",X"FC",X"BD",X"F5",X"75", + X"7E",X"F4",X"95",X"8D",X"EE",X"A6",X"C4",X"26",X"FA",X"39",X"8D",X"EC",X"A6",X"C4",X"26",X"FA", + X"39",X"AE",X"84",X"34",X"04",X"C6",X"80",X"33",X"78",X"36",X"06",X"35",X"02",X"81",X"09",X"23", + X"02",X"86",X"3C",X"8B",X"30",X"C6",X"2D",X"36",X"06",X"36",X"10",X"20",X"CB",X"A6",X"80",X"20", + X"08",X"D7",X"04",X"20",X"07",X"EC",X"81",X"D7",X"04",X"B7",X"C8",X"23",X"EC",X"84",X"97",X"01", + X"0F",X"00",X"30",X"02",X"12",X"0C",X"00",X"D7",X"01",X"CC",X"00",X"00",X"20",X"1F",X"A6",X"80", + X"20",X"08",X"D7",X"04",X"20",X"07",X"EC",X"81",X"D7",X"04",X"B7",X"C8",X"23",X"EC",X"84",X"97", + X"01",X"0F",X"00",X"30",X"02",X"12",X"0C",X"00",X"D7",X"01",X"CC",X"FF",X"00",X"97",X"0A",X"D7", + X"05",X"CC",X"00",X"40",X"D5",X"0D",X"27",X"FC",X"12",X"97",X"0A",X"B6",X"C8",X"23",X"4A",X"2A", + X"D9",X"7E",X"F3",X"4F",X"C6",X"FF",X"20",X"06",X"C6",X"7F",X"20",X"02",X"E6",X"80",X"D7",X"04", + X"EC",X"01",X"97",X"01",X"0F",X"00",X"A6",X"84",X"30",X"03",X"0C",X"00",X"D7",X"01",X"97",X"0A", + X"0F",X"05",X"CC",X"00",X"40",X"D5",X"0D",X"27",X"FC",X"12",X"97",X"0A",X"A6",X"84",X"2F",X"E0", + X"7E",X"F3",X"4F",X"4A",X"B7",X"C8",X"23",X"EC",X"84",X"97",X"01",X"0F",X"00",X"30",X"02",X"0C", + X"00",X"D7",X"01",X"B6",X"C8",X"29",X"C6",X"40",X"97",X"0A",X"0F",X"05",X"F5",X"D0",X"0D",X"27", + X"0B",X"0F",X"0A",X"B6",X"C8",X"23",X"26",X"DB",X"39",X"B6",X"C8",X"29",X"97",X"0A",X"12",X"D5", + X"0D",X"27",X"F6",X"B6",X"C8",X"23",X"0F",X"0A",X"4D",X"26",X"C8",X"7E",X"F3",X"4F",X"B6",X"C8", + X"24",X"34",X"02",X"7F",X"C8",X"24",X"A6",X"80",X"2A",X"04",X"8D",X"BB",X"20",X"F8",X"26",X"05", + X"BD",X"F3",X"BC",X"20",X"F1",X"4A",X"27",X"05",X"BD",X"F3",X"DD",X"20",X"E9",X"35",X"02",X"B7", + X"C8",X"24",X"7E",X"F3",X"4F",X"FF",X"C8",X"2C",X"8E",X"F9",X"D4",X"CC",X"18",X"83",X"0F",X"01", + X"97",X"0B",X"8E",X"F9",X"D4",X"D7",X"00",X"0A",X"00",X"CC",X"80",X"81",X"12",X"0C",X"00",X"D7", + X"00",X"97",X"00",X"7D",X"C8",X"00",X"0C",X"00",X"B6",X"C8",X"2B",X"97",X"01",X"CC",X"01",X"00", + X"FE",X"C8",X"2C",X"97",X"00",X"20",X"04",X"A6",X"86",X"97",X"0A",X"A6",X"C0",X"2A",X"F8",X"86", + X"81",X"97",X"00",X"00",X"01",X"86",X"01",X"97",X"00",X"8C",X"FB",X"B4",X"27",X"2C",X"30",X"88", + X"50",X"1F",X"30",X"B3",X"C8",X"2C",X"C0",X"02",X"58",X"21",X"00",X"86",X"81",X"12",X"5A",X"26", + X"FA",X"97",X"00",X"F6",X"C8",X"2A",X"D7",X"01",X"0A",X"00",X"CC",X"81",X"01",X"12",X"97",X"00", + X"0F",X"01",X"D7",X"00",X"97",X"00",X"C6",X"03",X"20",X"9B",X"86",X"98",X"97",X"0B",X"7E",X"F3", + X"54",X"34",X"14",X"C6",X"02",X"20",X"03",X"34",X"14",X"5F",X"BE",X"C8",X"7B",X"A6",X"01",X"49", + X"49",X"49",X"49",X"A8",X"02",X"46",X"69",X"84",X"69",X"01",X"69",X"02",X"5A",X"2A",X"EE",X"A6", + X"84",X"35",X"94",X"C6",X"0D",X"8E",X"C8",X"3F",X"8D",X"05",X"86",X"3F",X"A7",X"06",X"39",X"4F", + X"20",X"06",X"8E",X"C8",X"00",X"CC",X"00",X"FF",X"6F",X"8B",X"83",X"00",X"01",X"2A",X"F9",X"39", + X"86",X"80",X"A7",X"85",X"5A",X"26",X"FB",X"A7",X"84",X"39",X"C6",X"02",X"20",X"02",X"C6",X"05", + X"8E",X"C8",X"2E",X"6D",X"85",X"27",X"02",X"6A",X"85",X"5A",X"2A",X"F7",X"39",X"C6",X"03",X"20", + X"09",X"C6",X"02",X"20",X"05",X"C6",X"01",X"20",X"01",X"5F",X"5A",X"2A",X"FD",X"39",X"8E",X"F9", + X"DC",X"A6",X"86",X"39",X"4D",X"2A",X"04",X"40",X"28",X"01",X"4A",X"5D",X"2A",X"04",X"50",X"28", + X"01",X"5A",X"39",X"34",X"10",X"DD",X"34",X"59",X"C6",X"00",X"59",X"49",X"59",X"58",X"D7",X"36", + X"DC",X"34",X"8D",X"E0",X"97",X"34",X"D1",X"34",X"23",X"08",X"0C",X"36",X"1E",X"89",X"20",X"02", + X"44",X"54",X"81",X"09",X"22",X"FA",X"DD",X"34",X"D6",X"36",X"8E",X"FC",X"24",X"E6",X"85",X"8E", + X"FC",X"2C",X"A6",X"86",X"9B",X"35",X"8B",X"0A",X"C5",X"01",X"26",X"04",X"EB",X"86",X"20",X"03", + X"5A",X"E0",X"86",X"D7",X"36",X"96",X"36",X"35",X"90",X"8B",X"10",X"8E",X"FC",X"6D",X"5F",X"85", + X"20",X"27",X"02",X"C6",X"80",X"84",X"1F",X"81",X"10",X"26",X"01",X"5C",X"A6",X"86",X"39",X"34", + X"10",X"96",X"36",X"8D",X"E6",X"DD",X"37",X"96",X"36",X"8D",X"DE",X"DD",X"39",X"35",X"90",X"C0", + X"10",X"D7",X"36",X"97",X"3B",X"8D",X"E8",X"8D",X"54",X"40",X"34",X"02",X"8D",X"55",X"35",X"84", + X"B7",X"C8",X"36",X"F7",X"C8",X"23",X"34",X"08",X"BD",X"F1",X"AF",X"8D",X"D2",X"20",X"18",X"B7", + X"C8",X"36",X"34",X"08",X"BD",X"F1",X"AF",X"97",X"23",X"8D",X"C4",X"A6",X"80",X"A7",X"C0",X"2F", + X"06",X"0F",X"23",X"35",X"88",X"0A",X"23",X"A6",X"80",X"8D",X"26",X"A7",X"C4",X"A6",X"84",X"8D", + X"1A",X"AB",X"C4",X"A7",X"C0",X"A6",X"1F",X"8D",X"12",X"A7",X"C4",X"A6",X"80",X"8D",X"12",X"A0", + X"C4",X"A7",X"C0",X"96",X"23",X"2B",X"D4",X"26",X"DC",X"35",X"88",X"97",X"3B",X"DC",X"37",X"20", + X"04",X"97",X"3B",X"DC",X"39",X"D7",X"3C",X"C5",X"01",X"27",X"04",X"96",X"3B",X"20",X"0A",X"D6", + X"3B",X"2A",X"03",X"03",X"3C",X"50",X"3D",X"89",X"00",X"D6",X"3C",X"2A",X"01",X"40",X"39",X"E6", + X"C6",X"E7",X"86",X"4A",X"2A",X"F9",X"39",X"96",X"56",X"2B",X"28",X"27",X"F9",X"8E",X"FC",X"8D", + X"9F",X"4D",X"86",X"80",X"97",X"56",X"EC",X"C1",X"DD",X"4F",X"EC",X"C1",X"DD",X"51",X"DF",X"53", + X"BD",X"F5",X"33",X"CC",X"1F",X"1F",X"DD",X"5F",X"CC",X"00",X"00",X"DD",X"63",X"DD",X"65",X"97", + X"55",X"20",X"39",X"CE",X"C8",X"5E",X"C6",X"02",X"A6",X"C5",X"81",X"1F",X"27",X"02",X"6C",X"C5", + X"5A",X"2A",X"F5",X"9E",X"51",X"CE",X"C8",X"58",X"86",X"07",X"6C",X"C4",X"A1",X"C4",X"2C",X"02", + X"6F",X"C4",X"E6",X"C0",X"C4",X"07",X"E6",X"85",X"E7",X"C0",X"4C",X"81",X"09",X"23",X"EB",X"0A", + X"57",X"26",X"6B",X"96",X"55",X"4A",X"2A",X"02",X"86",X"02",X"97",X"55",X"E6",X"9F",X"C8",X"53", + X"CE",X"C8",X"5E",X"6F",X"C6",X"C5",X"40",X"27",X"19",X"8E",X"F9",X"E4",X"A6",X"86",X"94",X"45", + X"97",X"45",X"96",X"55",X"8B",X"03",X"A6",X"86",X"9A",X"45",X"97",X"45",X"C4",X"1F",X"D7",X"46", + X"20",X"23",X"8E",X"F9",X"EA",X"A6",X"86",X"94",X"45",X"97",X"45",X"96",X"55",X"8B",X"03",X"A6", + X"86",X"9A",X"45",X"97",X"45",X"96",X"55",X"48",X"8B",X"03",X"33",X"C6",X"C4",X"3F",X"58",X"9E", + X"4D",X"EC",X"85",X"ED",X"C4",X"9E",X"53",X"E6",X"80",X"9F",X"53",X"5D",X"2B",X"A5",X"E6",X"80", + X"2A",X"06",X"BD",X"F5",X"33",X"0F",X"56",X"39",X"9F",X"53",X"C4",X"3F",X"D7",X"57",X"10",X"9E", + X"4F",X"CE",X"C8",X"5E",X"8E",X"C8",X"42",X"86",X"02",X"E6",X"C0",X"C5",X"01",X"27",X"07",X"54", + X"E6",X"A5",X"C4",X"0F",X"20",X"07",X"54",X"E6",X"A5",X"54",X"54",X"54",X"54",X"E7",X"86",X"4A", + X"2A",X"E7",X"CE",X"C8",X"67",X"8E",X"C8",X"47",X"EC",X"C3",X"6D",X"58",X"2A",X"0A",X"60",X"58", + X"E0",X"58",X"82",X"00",X"60",X"58",X"20",X"04",X"EB",X"58",X"89",X"00",X"ED",X"81",X"8C",X"C8", + X"4D",X"26",X"E5",X"39",X"20",X"C0",X"40",X"C0",X"50",X"4C",X"41",X"59",X"45",X"52",X"80",X"E0", + X"C0",X"01",X"C0",X"20",X"47",X"41",X"4D",X"45",X"80",X"FD",X"C8",X"4F",X"4D",X"27",X"02",X"86", + X"01",X"5D",X"27",X"02",X"C6",X"01",X"FD",X"C8",X"79",X"BD",X"F1",X"AF",X"CC",X"F8",X"50",X"DD", + X"2A",X"97",X"3C",X"20",X"67",X"BD",X"F1",X"92",X"4F",X"BD",X"F1",X"B4",X"BD",X"F5",X"5A",X"BD", + X"F2",X"A9",X"B6",X"C8",X"79",X"10",X"8E",X"F7",X"94",X"8D",X"5A",X"B6",X"C8",X"7A",X"10",X"8E", + X"F7",X"9F",X"8D",X"51",X"BD",X"F1",X"AF",X"96",X"3C",X"27",X"06",X"96",X"0F",X"26",X"3D",X"0F", + X"3C",X"96",X"2F",X"27",X"9E",X"96",X"2E",X"26",X"CC",X"96",X"15",X"26",X"96",X"96",X"12",X"27", + X"0F",X"96",X"79",X"27",X"0B",X"4C",X"91",X"4F",X"23",X"02",X"86",X"01",X"97",X"79",X"20",X"1C", + X"96",X"7A",X"27",X"B1",X"D6",X"13",X"27",X"09",X"4C",X"91",X"50",X"23",X"0D",X"86",X"01",X"20", + X"09",X"D6",X"14",X"27",X"A0",X"4A",X"26",X"02",X"96",X"50",X"97",X"7A",X"86",X"F3",X"97",X"2F", + X"43",X"97",X"2E",X"20",X"90",X"8E",X"C8",X"5E",X"34",X"02",X"8D",X"13",X"A6",X"E0",X"27",X"0E", + X"8D",X"1C",X"1F",X"13",X"EC",X"A1",X"BD",X"F3",X"7A",X"1F",X"23",X"BD",X"F3",X"78",X"39",X"CC", + X"20",X"20",X"ED",X"84",X"ED",X"02",X"A7",X"04",X"CC",X"30",X"80",X"ED",X"05",X"39",X"CE",X"00", + X"00",X"81",X"63",X"23",X"08",X"80",X"64",X"33",X"C9",X"01",X"00",X"20",X"F4",X"81",X"09",X"23", + X"07",X"80",X"0A",X"33",X"C8",X"10",X"20",X"F5",X"33",X"C6",X"1F",X"30",X"34",X"02",X"34",X"04", + X"C6",X"05",X"4F",X"C1",X"01",X"23",X"10",X"C5",X"01",X"27",X"04",X"A6",X"E4",X"20",X"06",X"A6", + X"E0",X"44",X"44",X"44",X"44",X"84",X"0F",X"BB",X"C8",X"23",X"7F",X"C8",X"23",X"AB",X"85",X"81", + X"2F",X"2E",X"02",X"8B",X"10",X"81",X"39",X"23",X"05",X"80",X"0A",X"7C",X"C8",X"23",X"A7",X"85", + X"5A",X"2A",X"CF",X"7F",X"C8",X"23",X"5F",X"A6",X"85",X"81",X"30",X"26",X"09",X"86",X"20",X"A7", + X"85",X"5C",X"C1",X"05",X"2D",X"F1",X"39",X"34",X"50",X"4F",X"E6",X"80",X"2B",X"08",X"E1",X"C0", + X"27",X"F8",X"22",X"01",X"4C",X"4C",X"35",X"D0",X"8D",X"ED",X"81",X"01",X"26",X"06",X"A6",X"80", + X"A7",X"C0",X"2A",X"FA",X"39",X"34",X"20",X"34",X"36",X"EC",X"64",X"AB",X"C4",X"EB",X"41",X"ED", + X"64",X"20",X"10",X"34",X"20",X"34",X"36",X"1F",X"30",X"AB",X"64",X"EB",X"65",X"20",X"F0",X"34", + X"20",X"34",X"36",X"1F",X"41",X"5F",X"3A",X"A6",X"04",X"AB",X"84",X"28",X"02",X"86",X"7F",X"A1", + X"02",X"2D",X"15",X"A6",X"04",X"A0",X"84",X"28",X"02",X"86",X"80",X"A1",X"02",X"2E",X"09",X"5C", + X"C1",X"02",X"25",X"E2",X"1A",X"01",X"20",X"02",X"1C",X"FE",X"35",X"36",X"35",X"A0",X"96",X"67", + X"2A",X"29",X"84",X"7F",X"97",X"67",X"8E",X"C8",X"58",X"86",X"04",X"BD",X"F6",X"83",X"54",X"54", + X"54",X"DA",X"58",X"C4",X"07",X"D7",X"54",X"D6",X"58",X"C4",X"38",X"D7",X"53",X"D6",X"58",X"C4", + X"07",X"D7",X"5D",X"C6",X"02",X"D7",X"5C",X"86",X"7F",X"20",X"0D",X"96",X"77",X"27",X"6A",X"90", + X"5B",X"2A",X"05",X"5F",X"D7",X"77",X"20",X"62",X"97",X"77",X"44",X"44",X"D6",X"53",X"27",X"0D", + X"97",X"46",X"D6",X"59",X"2B",X"05",X"27",X"05",X"1F",X"89",X"53",X"D7",X"46",X"44",X"81",X"07", + X"23",X"05",X"81",X"0F",X"27",X"01",X"4C",X"D6",X"5A",X"2B",X"06",X"27",X"02",X"88",X"0F",X"1F", + X"89",X"8D",X"37",X"D6",X"5D",X"27",X"2B",X"96",X"5C",X"4A",X"2A",X"02",X"86",X"02",X"97",X"5C", + X"BD",X"F5",X"7E",X"95",X"5D",X"27",X"F0",X"D6",X"5C",X"58",X"50",X"8E",X"C8",X"4B",X"30",X"85", + X"BD",X"F5",X"17",X"84",X"0F",X"81",X"05",X"22",X"03",X"48",X"8B",X"05",X"A7",X"84",X"96",X"7E", + X"A7",X"01",X"96",X"58",X"43",X"94",X"45",X"97",X"45",X"39",X"96",X"54",X"8E",X"C8",X"45",X"4D", + X"27",X"09",X"30",X"1F",X"44",X"24",X"F8",X"E7",X"84",X"20",X"F4",X"39",X"01",X"02",X"04",X"08", + X"10",X"20",X"40",X"80",X"F7",X"EF",X"DF",X"01",X"02",X"04",X"FE",X"FD",X"FB",X"08",X"10",X"20", + X"7F",X"7F",X"80",X"80",X"00",X"20",X"50",X"50",X"20",X"C8",X"20",X"10",X"10",X"40",X"20",X"00", + X"00",X"00",X"00",X"08",X"30",X"20",X"70",X"70",X"10",X"F8",X"30",X"F8",X"70",X"70",X"00",X"60", + X"00",X"00",X"00",X"70",X"70",X"20",X"F0",X"70",X"F0",X"F8",X"F8",X"78",X"88",X"70",X"08",X"88", + X"80",X"88",X"88",X"F8",X"F0",X"70",X"F0",X"70",X"F8",X"88",X"88",X"88",X"88",X"88",X"F8",X"70", + X"80",X"70",X"20",X"00",X"00",X"20",X"08",X"20",X"00",X"00",X"00",X"38",X"10",X"20",X"44",X"44", + X"00",X"FE",X"FF",X"FE",X"00",X"70",X"50",X"50",X"78",X"C8",X"50",X"20",X"20",X"20",X"A8",X"20", + X"00",X"00",X"00",X"08",X"48",X"60",X"88",X"88",X"30",X"80",X"40",X"08",X"88",X"88",X"60",X"60", + X"10",X"00",X"40",X"88",X"88",X"50",X"48",X"88",X"48",X"80",X"80",X"80",X"88",X"20",X"08",X"90", + X"80",X"D8",X"C8",X"88",X"88",X"88",X"88",X"88",X"A8",X"88",X"88",X"88",X"88",X"88",X"08",X"40", + X"80",X"08",X"50",X"00",X"00",X"70",X"0C",X"20",X"70",X"70",X"00",X"44",X"10",X"70",X"00",X"00", + X"6C",X"82",X"FF",X"FE",X"00",X"70",X"50",X"F8",X"A0",X"10",X"50",X"40",X"40",X"10",X"70",X"20", + X"00",X"00",X"00",X"10",X"48",X"20",X"08",X"08",X"50",X"F0",X"80",X"10",X"88",X"88",X"60",X"00", + X"20",X"78",X"20",X"08",X"A8",X"88",X"48",X"80",X"48",X"80",X"80",X"80",X"88",X"20",X"08",X"A0", + X"80",X"A8",X"A8",X"88",X"88",X"88",X"88",X"40",X"20",X"88",X"88",X"88",X"50",X"50",X"10",X"40", + X"40",X"08",X"88",X"00",X"70",X"A8",X"0A",X"20",X"88",X"F8",X"60",X"BA",X"38",X"20",X"00",X"00", + X"92",X"82",X"FF",X"FE",X"00",X"20",X"00",X"50",X"70",X"20",X"60",X"00",X"40",X"10",X"A8",X"F8", + X"00",X"70",X"00",X"20",X"48",X"20",X"70",X"30",X"90",X"08",X"F0",X"20",X"70",X"78",X"00",X"60", + X"40",X"00",X"10",X"10",X"B8",X"88",X"70",X"80",X"48",X"E0",X"E0",X"98",X"F8",X"20",X"08",X"C0", + X"80",X"A8",X"98",X"88",X"F0",X"88",X"F0",X"20",X"20",X"88",X"50",X"A8",X"20",X"20",X"20",X"40", + X"20",X"08",X"00",X"00",X"FE",X"20",X"08",X"20",X"88",X"F8",X"F0",X"A2",X"38",X"F8",X"82",X"38", + X"92",X"82",X"FF",X"FE",X"00",X"00",X"00",X"F8",X"70",X"40",X"A8",X"00",X"40",X"10",X"A8",X"20", + X"40",X"00",X"00",X"40",X"48",X"20",X"80",X"08",X"F8",X"08",X"88",X"40",X"88",X"08",X"60",X"60", + X"20",X"78",X"20",X"20",X"B0",X"F8",X"48",X"80",X"48",X"80",X"80",X"88",X"88",X"20",X"08",X"A0", + X"80",X"88",X"88",X"88",X"80",X"A8",X"A0",X"10",X"20",X"88",X"50",X"A8",X"50",X"20",X"40",X"40", + X"10",X"08",X"00",X"00",X"FE",X"20",X"78",X"A8",X"88",X"F8",X"F0",X"BA",X"7C",X"20",X"44",X"44", + X"6C",X"82",X"FF",X"FE",X"00",X"00",X"00",X"50",X"28",X"98",X"90",X"00",X"20",X"20",X"00",X"20", + X"40",X"00",X"00",X"80",X"48",X"20",X"80",X"88",X"10",X"88",X"88",X"80",X"88",X"10",X"60",X"20", + X"10",X"00",X"40",X"00",X"80",X"88",X"48",X"88",X"48",X"80",X"80",X"88",X"88",X"20",X"88",X"90", + X"88",X"88",X"88",X"88",X"80",X"90",X"90",X"88",X"20",X"88",X"20",X"A8",X"88",X"20",X"80",X"40", + X"08",X"08",X"00",X"00",X"48",X"20",X"F0",X"70",X"70",X"70",X"60",X"44",X"6C",X"50",X"38",X"82", + X"00",X"82",X"FF",X"FE",X"00",X"20",X"00",X"50",X"F8",X"98",X"68",X"00",X"10",X"40",X"00",X"00", + X"80",X"00",X"80",X"80",X"30",X"70",X"F8",X"70",X"10",X"70",X"70",X"80",X"70",X"60",X"00",X"40", + X"00",X"00",X"00",X"20",X"78",X"88",X"F0",X"70",X"F0",X"F8",X"80",X"78",X"88",X"70",X"70",X"88", + X"F8",X"88",X"88",X"F8",X"80",X"68",X"88",X"70",X"20",X"70",X"20",X"50",X"88",X"20",X"F8",X"70", + X"08",X"70",X"00",X"F8",X"00",X"20",X"60",X"20",X"00",X"00",X"00",X"38",X"82",X"88",X"00",X"00", + X"00",X"FE",X"FF",X"FE",X"00",X"11",X"41",X"30",X"21",X"10",X"20",X"31",X"00",X"01",X"03",X"06", + X"0A",X"0F",X"15",X"1C",X"24",X"2D",X"08",X"10",X"08",X"10",X"0B",X"08",X"10",X"0D",X"0A",X"08", + X"10",X"0E",X"0B",X"09",X"08",X"10",X"0E",X"0C",X"0A",X"09",X"08",X"10",X"0E",X"0D",X"0B",X"0A", + X"09",X"08",X"10",X"0F",X"0D",X"0C",X"0B",X"0A",X"09",X"08",X"10",X"0F",X"0E",X"0C",X"0B",X"0A", + X"09",X"09",X"08",X"10",X"0F",X"0E",X"0D",X"0C",X"0B",X"0A",X"09",X"09",X"08",X"00",X"19",X"32", + X"4A",X"62",X"79",X"8E",X"A2",X"B5",X"C6",X"D5",X"E2",X"ED",X"F5",X"FB",X"FF",X"FF",X"FF",X"FB", + X"F5",X"ED",X"E2",X"D5",X"C6",X"B5",X"A2",X"8E",X"79",X"62",X"4A",X"32",X"19",X"03",X"BD",X"03", + X"87",X"03",X"54",X"03",X"24",X"02",X"F7",X"02",X"CD",X"02",X"A4",X"02",X"7E",X"02",X"5B",X"02", + X"39",X"02",X"19",X"01",X"FB",X"01",X"DE",X"01",X"C3",X"01",X"AA",X"01",X"92",X"01",X"7C",X"01", + X"66",X"01",X"52",X"01",X"3F",X"01",X"2D",X"01",X"1C",X"01",X"0C",X"00",X"FD",X"00",X"EF",X"00", + X"E2",X"00",X"D5",X"00",X"C9",X"00",X"BE",X"00",X"B3",X"00",X"A9",X"00",X"A0",X"00",X"97",X"00", + X"8E",X"00",X"86",X"00",X"7F",X"00",X"78",X"00",X"71",X"00",X"6B",X"00",X"65",X"00",X"5F",X"00", + X"5A",X"00",X"55",X"00",X"50",X"00",X"4B",X"00",X"47",X"00",X"43",X"00",X"3F",X"00",X"3C",X"00", + X"38",X"00",X"35",X"00",X"32",X"00",X"2F",X"00",X"2D",X"00",X"2A",X"00",X"28",X"00",X"26",X"00", + X"24",X"00",X"22",X"00",X"20",X"00",X"1E",X"00",X"1C",X"00",X"1B",X"00",X"00",X"FE",X"E8",X"FE", + X"B6",X"93",X"1F",X"0C",X"93",X"1F",X"06",X"98",X"9F",X"24",X"3C",X"11",X"80",X"FD",X"69",X"FD", + X"79",X"21",X"07",X"21",X"07",X"21",X"07",X"21",X"07",X"21",X"07",X"21",X"07",X"21",X"0E",X"99", + X"9F",X"24",X"0E",X"95",X"9B",X"20",X"0E",X"21",X"07",X"21",X"07",X"21",X"07",X"21",X"07",X"21", + X"07",X"21",X"07",X"9D",X"A3",X"28",X"0E",X"A0",X"A6",X"2B",X"0E",X"22",X"02",X"28",X"02",X"2D", + X"02",X"28",X"02",X"22",X"02",X"28",X"02",X"2D",X"02",X"28",X"02",X"22",X"02",X"28",X"02",X"2D", + X"02",X"28",X"02",X"2E",X"02",X"2D",X"28",X"21",X"80",X"EF",X"FF",X"FE",X"DC",X"BA",X"00",X"00", + X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"01",X"02",X"01",X"00",X"FF",X"FE", + X"FF",X"FD",X"C3",X"FE",X"B6",X"51",X"24",X"50",X"06",X"50",X"06",X"50",X"0C",X"50",X"06",X"50", + X"06",X"50",X"04",X"50",X"04",X"50",X"04",X"50",X"18",X"50",X"04",X"50",X"04",X"50",X"04",X"50", + X"0C",X"50",X"0C",X"50",X"24",X"50",X"06",X"50",X"06",X"50",X"0C",X"50",X"06",X"50",X"06",X"50", + X"04",X"50",X"04",X"50",X"04",X"50",X"18",X"50",X"04",X"50",X"04",X"50",X"04",X"50",X"0C",X"50", + X"18",X"26",X"80",X"FD",X"BA",X"98",X"76",X"55",X"44",X"33",X"22",X"11",X"00",X"00",X"00",X"00", + X"00",X"00",X"00",X"FE",X"28",X"FD",X"79",X"98",X"1C",X"10",X"3F",X"08",X"98",X"1C",X"04",X"98", + X"1C",X"04",X"98",X"1C",X"10",X"3F",X"08",X"98",X"1C",X"04",X"98",X"1C",X"04",X"98",X"1C",X"08", + X"93",X"18",X"08",X"98",X"1C",X"08",X"9C",X"1F",X"08",X"98",X"1C",X"08",X"93",X"18",X"08",X"98", + X"1C",X"08",X"93",X"18",X"08",X"98",X"1C",X"08",X"9C",X"1F",X"08",X"98",X"1C",X"08",X"93",X"18", + X"08",X"98",X"1C",X"08",X"93",X"18",X"08",X"98",X"1C",X"08",X"9C",X"1F",X"08",X"98",X"1C",X"08", + X"93",X"18",X"08",X"9C",X"1F",X"30",X"1A",X"80",X"FF",X"FE",X"DC",X"BA",X"98",X"76",X"54",X"32", + X"10",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"FE",X"66",X"FE",X"B6",X"0C",X"18",X"11",X"18", + X"0C",X"18",X"11",X"18",X"0C",X"18",X"11",X"18",X"0C",X"12",X"0C",X"06",X"11",X"18",X"9D",X"21", + X"18",X"9F",X"23",X"18",X"A1",X"24",X"18",X"A3",X"26",X"18",X"9F",X"A4",X"28",X"18",X"07",X"12", + X"07",X"06",X"00",X"3C",X"18",X"80",X"DE",X"EF",X"FE",X"DC",X"BA",X"00",X"00",X"00",X"00",X"00", + X"00",X"00",X"00",X"00",X"00",X"00",X"FE",X"B2",X"FE",X"B6",X"18",X"06",X"1A",X"06",X"1C",X"0C", + X"18",X"0C",X"1A",X"24",X"23",X"18",X"17",X"06",X"18",X"06",X"1A",X"0C",X"17",X"0C",X"18",X"24", + X"24",X"18",X"A4",X"28",X"0C",X"A3",X"26",X"0C",X"A1",X"24",X"0C",X"9F",X"23",X"0C",X"9D",X"21", + X"18",X"9A",X"1F",X"18",X"17",X"06",X"18",X"06",X"1A",X"0C",X"17",X"0C",X"18",X"24",X"24",X"24", + X"18",X"80",X"FF",X"EE",X"DD",X"CC",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00", + X"00",X"00",X"00",X"00",X"00",X"00",X"FE",X"E8",X"FE",X"B6",X"96",X"9A",X"1D",X"1E",X"91",X"95", + X"18",X"1E",X"94",X"98",X"1B",X"1E",X"8F",X"94",X"18",X"14",X"16",X"0A",X"8C",X"91",X"15",X"14", + X"16",X"0A",X"91",X"95",X"18",X"32",X"18",X"80",X"EE",X"FF",X"FF",X"EE",X"EE",X"DD",X"CC",X"BB", + X"AA",X"99",X"88",X"88",X"88",X"88",X"88",X"88",X"FF",X"16",X"FE",X"B6",X"1C",X"06",X"1F",X"06", + X"1C",X"06",X"18",X"06",X"1A",X"06",X"18",X"06",X"15",X"06",X"13",X"06",X"18",X"06",X"13",X"06", + X"17",X"06",X"18",X"1E",X"18",X"80",X"FF",X"FF",X"EE",X"EE",X"DD",X"DD",X"CC",X"CC",X"00",X"00", + X"00",X"00",X"00",X"00",X"00",X"00",X"FE",X"28",X"FE",X"B6",X"16",X"0F",X"16",X"05",X"16",X"05", + X"16",X"05",X"1A",X"0F",X"16",X"0F",X"1D",X"0F",X"1D",X"05",X"1D",X"05",X"1D",X"05",X"21",X"0F", + X"1D",X"32",X"1D",X"80",X"FE",X"28",X"FE",X"B6",X"16",X"06",X"16",X"02",X"16",X"02",X"16",X"02", + X"1A",X"06",X"16",X"06",X"1D",X"06",X"1D",X"02",X"1D",X"02",X"1D",X"02",X"21",X"06",X"1D",X"32", + X"11",X"80",X"FE",X"28",X"FE",X"B6",X"1B",X"0F",X"16",X"05",X"16",X"05",X"16",X"05",X"17",X"30", + X"16",X"05",X"16",X"05",X"16",X"05",X"17",X"30",X"16",X"80",X"FD",X"69",X"FE",X"B6",X"A0",X"23", + X"12",X"A0",X"23",X"0C",X"9C",X"20",X"06",X"9E",X"21",X"12",X"9C",X"20",X"32",X"13",X"80",X"FD", + X"C3",X"FE",X"B6",X"16",X"04",X"16",X"04",X"16",X"04",X"16",X"04",X"1A",X"08",X"1C",X"80",X"A6", + X"A0",X"20",X"08",X"BD",X"F3",X"BE",X"B6",X"C8",X"80",X"84",X"7F",X"B7",X"C8",X"80",X"7A",X"C8", + X"80",X"A6",X"A4",X"47",X"84",X"F8",X"E6",X"A0",X"58",X"58",X"58",X"58",X"57",X"C4",X"F8",X"7D", + X"C8",X"80",X"2B",X"DF",X"BD",X"F3",X"DF",X"B6",X"C8",X"80",X"85",X"0F",X"26",X"E0",X"85",X"20", + X"27",X"CD",X"39",X"4B",X"41",X"52",X"52",X"53",X"4F",X"46",X"54",X"38",X"32",X"4C",X"44",X"4D", + X"43",X"42",X"43",X"4A",X"54",X"38",X"32",X"4C",X"44",X"4D",X"43",X"42",X"43",X"4A",X"00",X"00", + X"00",X"00",X"CB",X"F2",X"CB",X"F2",X"CB",X"F5",X"CB",X"F8",X"CB",X"FB",X"CB",X"FB",X"F0",X"00"); +begin +process(clk) +begin + if rising_edge(clk) then + data <= rom_data(to_integer(unsigned(addr))); + end if; +end process; +end architecture; diff --git a/GCE - Vectrex_MiST/rtl/vectrex_mist.sv b/GCE - Vectrex_MiST/rtl/vectrex_mist.sv new file mode 100644 index 00000000..0c595d3e --- /dev/null +++ b/GCE - Vectrex_MiST/rtl/vectrex_mist.sv @@ -0,0 +1,179 @@ +module vectrex_mist +( + output LED, + output [5:0] VGA_R, + output [5:0] VGA_G, + output [5:0] VGA_B, + output VGA_HS, + output VGA_VS, + output AUDIO_L, + output AUDIO_R, + input SPI_SCK, + output SPI_DO, + input SPI_DI, + input SPI_SS2, + input SPI_SS3, + input CONF_DATA0, + input CLOCK_27 +); + +`include "rtl\build_id.v" + +localparam CONF_STR = { + "Vectrex;BINVEC;", + "T6,Reset;", + "V,v1.00.",`BUILD_DATE +}; + +wire [31:0] status; +wire [1:0] buttons; +wire [1:0] switches; +wire [9:0] kbjoy; +wire [7:0] joystick_0; +wire [7:0] joystick_1; +wire ypbpr; +wire ps2_kbd_clk, ps2_kbd_data; +wire [7:0] pot_x; +wire [7:0] pot_y; +wire [9:0] audio; +wire hs, vs, cs; +wire [3:0] r, g, b; +wire blankn; +wire cart_rd; +wire [14:0] cart_addr; +wire [7:0] cart_do; +wire ioctl_downl; +wire [7:0] ioctl_index; +wire ioctl_wr; +wire [14:0] ioctl_addr; +wire [7:0] ioctl_dout; + + +assign LED = !ioctl_downl; + +wire clk_25, clk_12p5, clk_6p25, cpu_clock; +wire pll_locked; + +always @(clk_6p25)begin + pot_x = 8'h00; + pot_y = 8'h00; + if (joystick_0[3] | joystick_1[3] | kbjoy[3]) pot_y = 8'h7F; + if (joystick_0[2] | joystick_1[2] | kbjoy[2]) pot_y = 8'h80; + if (joystick_0[1] | joystick_1[1] | kbjoy[1]) pot_x = 8'h80; + if (joystick_0[0] | joystick_1[0] | kbjoy[0]) pot_x = 8'h7F; +end + +pll pll ( + .inclk0 ( CLOCK_27 ), + .areset ( 0 ), + .c0 ( clk_25 ), + .c1 ( clk_12p5 ), + .c2 ( clk_6p25 ), + .locked ( pll_locked ) + ); + +card card ( + .clock ( cpu_clock ), + .address ( ioctl_downl ? ioctl_addr : cart_addr),//16kb only for now + .data ( ioctl_dout ), + .rden ( !ioctl_downl && cart_rd), + .wren ( ioctl_downl && ioctl_wr), + .q ( cart_do ) + ); + +vectrex vectrex ( + .clock_24 ( clk_25 ), + .clock_12 ( clk_12p5 ), + .cpu_clock_o ( cpu_clock ), + .reset ( status[0] | status[6] | buttons[1] | ioctl_downl), + .video_r ( r ), + .video_g ( g ), + .video_b ( b ), + .video_csync ( ), + .video_blankn ( blankn ), + .video_hs ( hs ), + .video_vs ( vs ), + .audio_out ( audio ), + .cart_addr ( cart_addr ), + .cart_do ( cart_do ), + .cart_rd ( cart_rd ), + .rt_1 ( joystick_0[4] | joystick_1[4] | kbjoy[4]),//1 + .lf_1 ( joystick_0[5] | joystick_1[5] | kbjoy[5]),//2 + .dn_1 ( kbjoy[6] ),//3 + .up_1 ( kbjoy[7] ),//4 + .pot_x_1 ( pot_x ), + .pot_y_1 ( pot_y ), + .rt_2 ( joystick_0[4] | joystick_1[4] | kbjoy[4]),//1 + .lf_2 ( joystick_0[5] | joystick_1[5 ] | kbjoy[5]),//2 + .dn_2 ( kbjoy[6] ),//3 + .up_2 ( kbjoy[7] ),//4 + .pot_x_2 ( pot_x ), + .pot_y_2 ( pot_y ), + .leds ( ), + .dbg_cpu_addr ( ) + ); + +dac dac ( + .clk_i ( clk_25 ), + .res_n_i ( 1 ), + .dac_i ( audio ), + .dac_o ( AUDIO_L ) + ); +assign AUDIO_R = AUDIO_L; + +video_mixer #(.LINE_LENGTH(640), .HALF_DEPTH(1)) video_mixer ( + .clk_sys ( clk_25 ), + .ce_pix ( clk_6p25 ), + .ce_pix_actual ( clk_6p25 ), + .SPI_SCK ( SPI_SCK ), + .SPI_SS3 ( SPI_SS3 ), + .SPI_DI ( SPI_DI ), + .R ( blankn ? r : "0000"), + .G ( blankn ? g : "0000"), + .B ( blankn ? b : "0000"), + .HSync ( hs ), + .VSync ( vs ), + .VGA_R ( VGA_R ), + .VGA_G ( VGA_G ), + .VGA_B ( VGA_B ), + .VGA_VS ( VGA_VS ), + .VGA_HS ( VGA_HS ), + .scandoubler_disable(1 ), + .ypbpr_full ( 1 ), + .line_start ( 0 ), + .mono ( 0 ) + ); + +mist_io #(.STRLEN(($size(CONF_STR)>>3))) mist_io ( + .clk_sys ( clk_25 ), + .conf_str ( CONF_STR ), + .SPI_SCK ( SPI_SCK ), + .CONF_DATA0 ( CONF_DATA0 ), + .SPI_SS2 ( SPI_SS2 ), + .SPI_DO ( SPI_DO ), + .SPI_DI ( SPI_DI ), + .buttons ( buttons ), + .switches ( switches ), + .ypbpr ( ypbpr ), + .ps2_kbd_clk ( ps2_kbd_clk ), + .ps2_kbd_data ( ps2_kbd_data ), + .joystick_0 ( joystick_0 ), + .joystick_1 ( joystick_1 ), + .status ( status ), + .ioctl_download( ioctl_downl ), + .ioctl_index ( ioctl_index ), + .ioctl_wr ( ioctl_wr ), + .ioctl_addr ( ioctl_addr ), + .ioctl_dout ( ioctl_dout ) + ); + +keyboard keyboard ( + .clk ( clk_25 ), + .reset ( ), + .ps2_kbd_clk ( ps2_kbd_clk ), + .ps2_kbd_data ( ps2_kbd_data ), + .joystick ( kbjoy ) + ); + + +endmodule \ No newline at end of file diff --git a/GCE - Vectrex_MiST/rtl/vectrex_scramble_prom.vhd b/GCE - Vectrex_MiST/rtl/vectrex_scramble_prom.vhd new file mode 100644 index 00000000..a903961a --- /dev/null +++ b/GCE - Vectrex_MiST/rtl/vectrex_scramble_prom.vhd @@ -0,0 +1,278 @@ +library ieee; +use ieee.std_logic_1164.all,ieee.numeric_std.all; + +entity vectrex_scramble_prom is +port ( + clk : in std_logic; + addr : in std_logic_vector(11 downto 0); + data : out std_logic_vector(7 downto 0) +); +end entity; + +architecture prom of vectrex_scramble_prom is + type rom is array(0 to 4095) of std_logic_vector(7 downto 0); + signal rom_data: rom := ( + X"67",X"20",X"47",X"43",X"45",X"20",X"31",X"39",X"38",X"32",X"80",X"FD",X"D3",X"F8",X"50",X"20", + X"C8",X"53",X"43",X"52",X"41",X"4D",X"42",X"4C",X"45",X"80",X"00",X"BD",X"F1",X"8B",X"BD",X"F1", + X"AF",X"CC",X"02",X"03",X"BD",X"F7",X"A9",X"0A",X"79",X"0A",X"7A",X"0A",X"7A",X"86",X"01",X"0F", + X"21",X"0F",X"22",X"20",X"41",X"8E",X"C8",X"A6",X"C6",X"35",X"BD",X"F5",X"50",X"8E",X"C9",X"4D", + X"6F",X"80",X"EC",X"81",X"8C",X"C9",X"65",X"26",X"F7",X"CC",X"01",X"DF",X"DD",X"C9",X"86",X"10", + X"97",X"FD",X"CC",X"28",X"A0",X"DD",X"C4",X"8E",X"C8",X"80",X"CC",X"B6",X"00",X"ED",X"81",X"8C", + X"C8",X"A4",X"26",X"F9",X"96",X"A4",X"48",X"48",X"48",X"48",X"97",X"A3",X"BD",X"F5",X"17",X"84", + X"06",X"8B",X"0E",X"97",X"C3",X"39",X"86",X"05",X"97",X"FE",X"0D",X"79",X"26",X"02",X"86",X"FF", + X"97",X"FF",X"0F",X"E5",X"8E",X"C9",X"3A",X"BD",X"F8",X"4F",X"30",X"14",X"BD",X"F8",X"4F",X"30", + X"1C",X"CC",X"F8",X"30",X"ED",X"84",X"ED",X"0C",X"86",X"7F",X"ED",X"0E",X"C6",X"B0",X"ED",X"02", + X"6F",X"1F",X"6F",X"0B",X"CC",X"0F",X"01",X"DD",X"F9",X"86",X"02",X"97",X"F4",X"97",X"F5",X"D7", + X"F3",X"BD",X"0E",X"C7",X"0F",X"F6",X"D6",X"F3",X"5C",X"C4",X"01",X"0D",X"79",X"26",X"01",X"5F", + X"D7",X"F3",X"4F",X"1F",X"01",X"E6",X"89",X"C8",X"F4",X"D7",X"A4",X"5A",X"5A",X"1F",X"02",X"EC", + X"A9",X"0A",X"3A",X"DD",X"FB",X"EC",X"A9",X"0A",X"48",X"DD",X"EF",X"0F",X"C7",X"0F",X"E4",X"6A", + X"89",X"C8",X"FE",X"2A",X"0E",X"DC",X"FE",X"84",X"80",X"C4",X"80",X"10",X"83",X"80",X"80",X"26", + X"C0",X"20",X"83",X"BD",X"00",X"35",X"0C",X"6A",X"0D",X"F6",X"27",X"0E",X"BD",X"F6",X"87",X"0D", + X"56",X"26",X"0A",X"0F",X"F6",X"BD",X"0E",X"C7",X"20",X"03",X"BD",X"0E",X"E2",X"BD",X"02",X"87", + X"0D",X"DB",X"2B",X"0E",X"0D",X"E5",X"2B",X"0A",X"D6",X"11",X"C4",X"F0",X"C1",X"F0",X"26",X"02", + X"0A",X"E5",X"DC",X"1B",X"1E",X"89",X"DD",X"EA",X"0D",X"DB",X"2A",X"08",X"96",X"C7",X"80",X"02", + X"84",X"0E",X"97",X"C7",X"D6",X"F3",X"4F",X"1F",X"02",X"96",X"A3",X"44",X"44",X"44",X"44",X"84", + X"FE",X"97",X"A4",X"A7",X"A9",X"C8",X"F4",X"7E",X"03",X"04",X"DC",X"C4",X"9E",X"C9",X"27",X"06", + X"0D",X"EA",X"27",X"0C",X"2A",X"04",X"4A",X"4A",X"20",X"06",X"81",X"5E",X"2C",X"02",X"4C",X"4C", + X"0D",X"EB",X"27",X"0F",X"2A",X"08",X"C1",X"A0",X"2D",X"09",X"5A",X"5A",X"20",X"05",X"5D",X"2A", + X"02",X"5C",X"5C",X"DD",X"C4",X"1F",X"01",X"86",X"0D",X"BD",X"02",X"6F",X"10",X"8E",X"C8",X"CB", + X"EC",X"A1",X"C1",X"70",X"2E",X"1D",X"CB",X"04",X"ED",X"3E",X"1F",X"01",X"86",X"FF",X"97",X"A5", + X"BD",X"08",X"23",X"24",X"09",X"96",X"A5",X"2B",X"0A",X"BD",X"09",X"5A",X"20",X"05",X"BD",X"02", + X"F9",X"20",X"05",X"CC",X"80",X"80",X"ED",X"3E",X"10",X"8C",X"C8",X"D3",X"26",X"D2",X"D6",X"11", + X"C4",X"0A",X"27",X"1C",X"8E",X"C8",X"CC",X"E6",X"81",X"C1",X"80",X"26",X"0E",X"DC",X"C4",X"CB", + X"0E",X"ED",X"1D",X"96",X"67",X"8A",X"20",X"97",X"67",X"20",X"05",X"8C",X"C8",X"D4",X"26",X"E7", + X"10",X"8E",X"C8",X"D3",X"EC",X"A1",X"C1",X"90",X"2D",X"24",X"80",X"02",X"6D",X"22",X"27",X"09", + X"6A",X"22",X"E6",X"22",X"4C",X"54",X"54",X"EB",X"3F",X"ED",X"3E",X"1F",X"01",X"0F",X"A5",X"BD", + X"08",X"23",X"25",X"07",X"86",X"0B",X"BD",X"02",X"6F",X"20",X"08",X"BD",X"09",X"5A",X"CC",X"80", + X"80",X"ED",X"3E",X"10",X"8C",X"C8",X"D7",X"26",X"CB",X"D6",X"11",X"C4",X"05",X"27",X"20",X"8E", + X"C8",X"D3",X"EC",X"81",X"81",X"80",X"26",X"12",X"DC",X"C4",X"CB",X"08",X"ED",X"1E",X"86",X"08", + X"A7",X"02",X"96",X"67",X"8A",X"08",X"97",X"67",X"20",X"05",X"8C",X"C8",X"D7",X"26",X"E3",X"CE", + X"08",X"1D",X"DC",X"C4",X"0D",X"7A",X"2B",X"02",X"AB",X"43",X"EB",X"C4",X"1F",X"01",X"86",X"FF", + X"97",X"A5",X"BD",X"08",X"23",X"24",X"0B",X"96",X"A5",X"2B",X"03",X"BD",X"09",X"5A",X"BD",X"08", + X"0C",X"39",X"33",X"41",X"11",X"83",X"08",X"20",X"26",X"D8",X"39",X"8E",X"00",X"10",X"5F",X"AD", + X"9F",X"C8",X"EC",X"39",X"97",X"C6",X"D6",X"C7",X"DA",X"C8",X"1F",X"01",X"8D",X"54",X"39",X"8D", + X"51",X"34",X"36",X"10",X"8E",X"0D",X"6B",X"48",X"31",X"A6",X"AE",X"A4",X"8D",X"73",X"C6",X"1F", + X"D7",X"04",X"BD",X"F4",X"10",X"20",X"5C",X"BD",X"F1",X"92",X"8E",X"C8",X"00",X"CE",X"C8",X"3F", + X"86",X"0D",X"E6",X"C0",X"BD",X"F2",X"59",X"4A",X"2A",X"F8",X"BD",X"F1",X"F8",X"BD",X"F1",X"BA", + X"BD",X"F2",X"A5",X"BD",X"F1",X"AF",X"39",X"34",X"76",X"8E",X"C9",X"2E",X"0D",X"F3",X"27",X"02", + X"30",X"0C",X"BD",X"F8",X"7C",X"35",X"F6",X"34",X"36",X"8D",X"36",X"8D",X"2B",X"CC",X"F3",X"73", + X"20",X"18",X"34",X"36",X"8D",X"2B",X"8D",X"20",X"20",X"04",X"34",X"36",X"8D",X"23",X"CC",X"F3", + X"12",X"20",X"07",X"34",X"36",X"8D",X"1A",X"CC",X"F3",X"DF",X"FD",X"C8",X"E8",X"EC",X"62",X"AD", + X"9F",X"C8",X"E8",X"BD",X"F1",X"AF",X"35",X"B6",X"BD",X"F3",X"54",X"86",X"CE",X"B7",X"D0",X"0C", + X"39",X"BD",X"F1",X"AA",X"86",X"7F",X"97",X"04",X"39",X"34",X"36",X"8D",X"F4",X"8D",X"E9",X"CC", + X"F2",X"C3",X"20",X"D6",X"CC",X"02",X"D3",X"DD",X"EC",X"10",X"8E",X"C8",X"80",X"EC",X"A1",X"84", + X"F0",X"C4",X"0F",X"D7",X"B1",X"BD",X"02",X"64",X"9F",X"DE",X"10",X"8C",X"C8",X"82",X"26",X"06", + X"8E",X"00",X"F0",X"BD",X"02",X"CA",X"D6",X"B1",X"C1",X"04",X"27",X"14",X"A6",X"3F",X"2B",X"0B", + X"C6",X"08",X"A6",X"A4",X"84",X"F0",X"BD",X"09",X"B8",X"20",X"05",X"BD",X"02",X"5B",X"20",X"F2", + X"96",X"B1",X"27",X"1E",X"81",X"06",X"2A",X"1A",X"6D",X"3F",X"2A",X"13",X"9E",X"DE",X"BD",X"02", + X"C2",X"10",X"8C",X"C8",X"82",X"27",X"06",X"8E",X"00",X"10",X"BD",X"02",X"CA",X"96",X"B1",X"BD", + X"02",X"71",X"10",X"8C",X"C8",X"82",X"27",X"A5",X"96",X"C8",X"8B",X"10",X"97",X"C8",X"81",X"80", + X"26",X"9B",X"96",X"DB",X"2A",X"05",X"BD",X"01",X"4A",X"20",X"48",X"81",X"3E",X"2D",X"04",X"C6", + X"40",X"D7",X"67",X"44",X"25",X"02",X"0C",X"C5",X"CE",X"00",X"10",X"9E",X"C4",X"BD",X"02",X"C2", + X"86",X"3F",X"90",X"DB",X"48",X"B7",X"D0",X"04",X"BD",X"F1",X"AA",X"B6",X"C8",X"E7",X"31",X"C6", + X"EC",X"A9",X"0D",X"B5",X"BD",X"F3",X"12",X"BD",X"F1",X"AF",X"1F",X"30",X"1E",X"89",X"9B",X"E6", + X"81",X"15",X"2B",X"04",X"80",X"05",X"20",X"F8",X"BD",X"02",X"71",X"33",X"41",X"11",X"83",X"00", + X"15",X"26",X"C8",X"96",X"A4",X"85",X"04",X"26",X"3E",X"96",X"C7",X"81",X"08",X"26",X"38",X"10", + X"8E",X"C8",X"BF",X"EC",X"A1",X"10",X"83",X"80",X"80",X"27",X"08",X"10",X"8C",X"C8",X"C3",X"26", + X"F2",X"20",X"24",X"D6",X"C3",X"8E",X"C8",X"82",X"3A",X"EC",X"80",X"C4",X"0F",X"C1",X"02",X"26", + X"16",X"E6",X"84",X"CB",X"04",X"E7",X"84",X"84",X"F0",X"8B",X"08",X"D6",X"C3",X"58",X"58",X"58", + X"CB",X"90",X"ED",X"A3",X"BD",X"00",X"6C",X"10",X"8E",X"C8",X"BF",X"EC",X"A1",X"10",X"83",X"80", + X"80",X"27",X"2D",X"8B",X"02",X"81",X"70",X"27",X"22",X"0D",X"DB",X"2A",X"13",X"C0",X"02",X"0D", + X"7A",X"2B",X"09",X"85",X"03",X"26",X"05",X"D1",X"C5",X"2D",X"01",X"5A",X"C1",X"88",X"2D",X"0B", + X"ED",X"3E",X"1F",X"01",X"86",X"06",X"BD",X"02",X"6F",X"20",X"05",X"CC",X"80",X"80",X"ED",X"3E", + X"10",X"8C",X"C8",X"C3",X"26",X"C5",X"0D",X"DB",X"2A",X"1B",X"CE",X"C8",X"BF",X"CC",X"00",X"80", + X"DD",X"F7",X"EC",X"C1",X"BE",X"0D",X"A7",X"BD",X"04",X"DB",X"1F",X"12",X"BD",X"07",X"CA",X"11", + X"83",X"C8",X"C3",X"26",X"ED",X"96",X"A4",X"81",X"04",X"10",X"26",X"00",X"E3",X"10",X"8E",X"C8", + X"A6",X"4F",X"E6",X"28",X"1F",X"01",X"EC",X"A1",X"10",X"83",X"80",X"80",X"27",X"37",X"AB",X"89", + X"0D",X"7D",X"EB",X"89",X"04",X"9F",X"ED",X"3E",X"1F",X"01",X"86",X"0F",X"BD",X"02",X"6F",X"A6", + X"3E",X"E6",X"26",X"84",X"FE",X"2B",X"0C",X"81",X"28",X"25",X"0E",X"CA",X"02",X"20",X"0A",X"00", + X"FC",X"00",X"FC",X"81",X"E8",X"22",X"02",X"C4",X"FD",X"84",X"20",X"27",X"04",X"CA",X"01",X"20", + X"02",X"C4",X"FE",X"E7",X"26",X"10",X"8C",X"C8",X"AE",X"26",X"B6",X"0D",X"DB",X"2A",X"59",X"CE", + X"C8",X"A6",X"CC",X"01",X"00",X"DD",X"F7",X"EC",X"C1",X"BE",X"0D",X"A9",X"8D",X"0D",X"1F",X"12", + X"BD",X"07",X"CA",X"11",X"83",X"C8",X"AE",X"26",X"EE",X"20",X"3D",X"34",X"36",X"10",X"8E",X"C8", + X"CB",X"AE",X"A1",X"8C",X"80",X"80",X"27",X"17",X"10",X"8C",X"C8",X"D3",X"25",X"04",X"C1",X"20", + X"2E",X"0D",X"34",X"26",X"1F",X"02",X"EC",X"66",X"BD",X"F8",X"FF",X"35",X"26",X"25",X"08",X"10", + X"8C",X"C8",X"D7",X"26",X"DC",X"35",X"B6",X"BD",X"09",X"5A",X"CC",X"80",X"80",X"ED",X"A3",X"ED", + X"5E",X"DC",X"F7",X"BD",X"02",X"A7",X"35",X"B6",X"D6",X"A7",X"C4",X"FC",X"C1",X"80",X"26",X"05", + X"CC",X"80",X"80",X"DD",X"A6",X"0A",X"FD",X"26",X"27",X"86",X"20",X"97",X"FD",X"10",X"8E",X"C8", + X"A6",X"A6",X"2A",X"A7",X"28",X"EC",X"22",X"ED",X"A1",X"10",X"8C",X"C8",X"AC",X"26",X"F2",X"BD", + X"F5",X"17",X"84",X"0F",X"1F",X"89",X"CB",X"70",X"8B",X"10",X"DD",X"AC",X"86",X"01",X"97",X"B4", + X"96",X"A4",X"81",X"06",X"26",X"59",X"CE",X"C8",X"B7",X"EC",X"C1",X"C4",X"F8",X"C1",X"80",X"26", + X"07",X"CC",X"80",X"80",X"ED",X"5E",X"20",X"1A",X"EC",X"5E",X"C0",X"08",X"D0",X"7A",X"ED",X"5E", + X"0D",X"DB",X"2A",X"07",X"10",X"BE",X"0D",X"A9",X"BD",X"07",X"CA",X"AE",X"5E",X"86",X"0E",X"BD", + X"02",X"6F",X"11",X"83",X"C8",X"BF",X"26",X"D1",X"D6",X"BE",X"C1",X"40",X"2C",X"21",X"10",X"8E", + X"C8",X"B9",X"EC",X"A4",X"ED",X"A3",X"31",X"24",X"10",X"8C",X"C8",X"C3",X"26",X"F4",X"BD",X"F5", + X"17",X"84",X"F8",X"81",X"60",X"2E",X"F7",X"81",X"D8",X"2D",X"F3",X"C6",X"7F",X"DD",X"BD",X"BD", + X"09",X"86",X"96",X"80",X"48",X"48",X"48",X"48",X"BD",X"02",X"64",X"8E",X"00",X"F0",X"BD",X"02", + X"CA",X"10",X"8E",X"C8",X"82",X"A6",X"A0",X"48",X"48",X"48",X"48",X"97",X"B1",X"91",X"C6",X"26", + X"09",X"81",X"60",X"26",X"05",X"CC",X"02",X"CA",X"20",X"03",X"CC",X"02",X"D3",X"DD",X"EC",X"96", + X"B1",X"E6",X"A0",X"2A",X"07",X"BD",X"02",X"5B",X"96",X"B1",X"20",X"02",X"C6",X"08",X"BD",X"09", + X"B8",X"96",X"B1",X"97",X"C6",X"10",X"8C",X"C8",X"A4",X"26",X"CA",X"DC",X"D3",X"10",X"83",X"80", + X"80",X"26",X"0E",X"DC",X"D5",X"10",X"83",X"80",X"80",X"26",X"06",X"96",X"67",X"8A",X"10",X"97", + X"67",X"4F",X"D6",X"7A",X"CB",X"04",X"DD",X"DC",X"DC",X"C9",X"0D",X"DB",X"2A",X"0D",X"0D",X"C7", + X"26",X"09",X"93",X"DC",X"2A",X"03",X"CC",X"00",X"00",X"DD",X"C9",X"10",X"83",X"00",X"77",X"24", + X"06",X"96",X"6A",X"84",X"08",X"27",X"20",X"8E",X"98",X"B0",X"BD",X"02",X"C2",X"96",X"C9",X"27", + X"06",X"8E",X"00",X"50",X"BD",X"02",X"D3",X"D6",X"CA",X"54",X"54",X"D7",X"EE",X"54",X"54",X"DB", + X"EE",X"4F",X"1F",X"01",X"BD",X"02",X"D3",X"96",X"67",X"9E",X"C9",X"8C",X"00",X"77",X"22",X"04", + X"8A",X"02",X"20",X"02",X"8A",X"01",X"97",X"67",X"8E",X"C9",X"29",X"CE",X"C8",X"FE",X"6D",X"84", + X"26",X"19",X"A6",X"06",X"81",X"31",X"26",X"13",X"6C",X"84",X"6C",X"C4",X"34",X"40",X"BD",X"0E", + X"C7",X"CE",X"FF",X"8F",X"BD",X"F6",X"8D",X"0C",X"F6",X"35",X"40",X"30",X"0C",X"33",X"41",X"11", + X"83",X"C9",X"00",X"26",X"D9",X"CC",X"FC",X"38",X"DD",X"2A",X"0D",X"F3",X"27",X"07",X"8E",X"88", + X"44",X"D6",X"FF",X"20",X"05",X"8E",X"88",X"A0",X"D6",X"FE",X"2B",X"12",X"86",X"68",X"34",X"16", + X"BD",X"02",X"F1",X"BD",X"02",X"E8",X"35",X"16",X"BD",X"F3",X"93",X"BD",X"F1",X"AF",X"0D",X"DB", + X"10",X"2A",X"00",X"9E",X"96",X"C7",X"10",X"26",X"00",X"98",X"D6",X"F0",X"54",X"25",X"06",X"CC", + X"00",X"10",X"BD",X"02",X"A7",X"8E",X"C8",X"82",X"EC",X"84",X"ED",X"83",X"30",X"04",X"8C",X"C8", + X"A4",X"26",X"F5",X"DE",X"FB",X"9E",X"EF",X"30",X"01",X"A6",X"89",X"0B",X"63",X"85",X"10",X"26", + X"0E",X"33",X"41",X"11",X"83",X"00",X"FC",X"26",X"06",X"CE",X"00",X"ED",X"8E",X"01",X"EB",X"DF", + X"FB",X"9F",X"EF",X"E6",X"89",X"0B",X"63",X"A6",X"C9",X"0A",X"66",X"DD",X"A2",X"C4",X"E0",X"C1", + X"A0",X"26",X"11",X"0D",X"7A",X"27",X"02",X"2A",X"0B",X"1F",X"89",X"C4",X"0F",X"C1",X"05",X"24", + X"03",X"4C",X"97",X"A2",X"D6",X"A3",X"C5",X"08",X"27",X"20",X"C4",X"F7",X"D7",X"A3",X"96",X"E4", + X"4C",X"84",X"01",X"97",X"E4",X"27",X"13",X"D6",X"A4",X"5A",X"5A",X"4F",X"1F",X"01",X"EC",X"89", + X"0A",X"56",X"DD",X"FB",X"EC",X"89",X"0A",X"5E",X"DD",X"EF",X"CC",X"01",X"6F",X"10",X"93",X"EF", + X"26",X"10",X"0D",X"E4",X"27",X"0C",X"0F",X"E4",X"CC",X"00",X"D0",X"DD",X"FB",X"CC",X"01",X"78", + X"DD",X"EF",X"CE",X"C9",X"2A",X"BD",X"02",X"B7",X"0D",X"79",X"27",X"06",X"CE",X"C9",X"36",X"BD", + X"02",X"B7",X"0D",X"DB",X"2B",X"41",X"0A",X"DB",X"26",X"3D",X"DC",X"FE",X"4A",X"10",X"2A",X"F9", + X"30",X"5A",X"10",X"2A",X"F9",X"2B",X"8E",X"C9",X"2E",X"8D",X"10",X"8E",X"C9",X"3A",X"8D",X"0B", + X"9E",X"F9",X"30",X"1E",X"9F",X"F9",X"2A",X"09",X"7E",X"F0",X"00",X"CE",X"CB",X"EB",X"7E",X"F8", + X"D8",X"96",X"11",X"84",X"0F",X"10",X"26",X"F8",X"CD",X"0C",X"DB",X"CE",X"07",X"BA",X"0D",X"E5", + X"2A",X"02",X"33",X"48",X"BD",X"02",X"B7",X"7E",X"00",X"F6",X"FC",X"38",X"28",X"F8",X"45",X"4E", + X"44",X"80",X"FC",X"38",X"28",X"F8",X"50",X"41",X"4E",X"80",X"34",X"26",X"10",X"8E",X"08",X"1D", + X"10",X"9F",X"F1",X"DC",X"C4",X"EB",X"A4",X"0D",X"7A",X"2B",X"02",X"AB",X"23",X"1F",X"01",X"EC", + X"E4",X"C1",X"14",X"2C",X"2E",X"1F",X"02",X"EC",X"62",X"BD",X"F8",X"FF",X"24",X"22",X"D6",X"A4", + X"C1",X"06",X"27",X"08",X"CC",X"80",X"80",X"ED",X"5E",X"BD",X"09",X"5A",X"86",X"3F",X"97",X"DB", + X"BD",X"F5",X"17",X"84",X"0F",X"97",X"E7",X"44",X"97",X"E6",X"35",X"A6",X"34",X"26",X"20",X"EC", + X"10",X"9E",X"F1",X"31",X"21",X"10",X"8C",X"08",X"20",X"26",X"B5",X"35",X"A6",X"0C",X"F8",X"FE", + X"00",X"04",X"FC",X"34",X"70",X"1F",X"10",X"97",X"B6",X"1F",X"98",X"C4",X"F0",X"D7",X"B5",X"84", + X"0F",X"90",X"C7",X"2A",X"08",X"C0",X"10",X"96",X"B5",X"80",X"10",X"97",X"B5",X"CB",X"80",X"54", + X"54",X"54",X"4F",X"1F",X"02",X"DD",X"E0",X"EC",X"A9",X"C8",X"82",X"97",X"D8",X"D7",X"B1",X"84", + X"F0",X"D6",X"C7",X"DA",X"B5",X"DD",X"DE",X"DD",X"E2",X"A6",X"A9",X"C8",X"84",X"97",X"DA",X"0D", + X"B1",X"2B",X"1A",X"D6",X"DA",X"C4",X"F0",X"96",X"D8",X"84",X"F0",X"9A",X"C7",X"BD",X"09",X"E6", + X"D7",X"EE",X"1F",X"10",X"91",X"EE",X"2E",X"0B",X"1A",X"01",X"7E",X"09",X"4C",X"D6",X"D8",X"C4", + X"F0",X"20",X"ED",X"0D",X"A5",X"27",X"30",X"96",X"D8",X"48",X"48",X"48",X"48",X"97",X"D8",X"D6", + X"DA",X"58",X"58",X"58",X"58",X"D7",X"DA",X"10",X"83",X"60",X"60",X"27",X"1A",X"0D",X"B1",X"2B", + X"12",X"9A",X"C7",X"BD",X"09",X"E6",X"D7",X"EE",X"1F",X"10",X"91",X"EE",X"2D",X"09",X"1A",X"01", + X"7E",X"09",X"4C",X"D6",X"D8",X"20",X"EF",X"96",X"B1",X"84",X"0F",X"97",X"B1",X"27",X"04",X"81", + X"06",X"2B",X"05",X"1C",X"FE",X"7E",X"09",X"4C",X"D6",X"E2",X"CB",X"10",X"D1",X"B6",X"2D",X"F3", + X"CE",X"0D",X"95",X"48",X"33",X"C6",X"10",X"AE",X"C4",X"EC",X"22",X"1F",X"23",X"10",X"9E",X"E2", + X"BD",X"F8",X"E5",X"24",X"67",X"D6",X"B1",X"C1",X"05",X"26",X"2C",X"34",X"36",X"CE",X"FD",X"D3", + X"BD",X"F6",X"8D",X"86",X"01",X"97",X"F6",X"CE",X"00",X"02",X"DF",X"FB",X"DF",X"EF",X"CE",X"01", + X"DF",X"DF",X"C9",X"0C",X"7A",X"8E",X"C8",X"B7",X"C6",X"08",X"BD",X"F5",X"50",X"8E",X"C8",X"A6", + X"C6",X"08",X"BD",X"F5",X"50",X"35",X"36",X"58",X"4F",X"1F",X"02",X"EC",X"A9",X"09",X"4E",X"BD", + X"02",X"A7",X"96",X"B1",X"81",X"01",X"26",X"0F",X"9E",X"C9",X"C6",X"40",X"3A",X"8C",X"01",X"DF", + X"2D",X"03",X"8E",X"01",X"DF",X"9F",X"C9",X"81",X"04",X"27",X"0F",X"10",X"9E",X"E0",X"A6",X"A9", + X"C8",X"83",X"84",X"F0",X"A7",X"A9",X"C8",X"83",X"0F",X"A5",X"1A",X"01",X"35",X"F0",X"00",X"00", + X"01",X"50",X"00",X"50",X"02",X"00",X"00",X"00",X"08",X"00",X"34",X"26",X"0F",X"B5",X"10",X"8E", + X"C9",X"4D",X"A6",X"A4",X"27",X"12",X"91",X"B5",X"2A",X"03",X"10",X"9F",X"DE",X"31",X"23",X"10", + X"8C",X"C9",X"65",X"26",X"ED",X"10",X"9E",X"DE",X"86",X"0F",X"A7",X"A0",X"AF",X"A4",X"96",X"67", + X"8A",X"04",X"97",X"67",X"35",X"A6",X"34",X"36",X"10",X"8E",X"C9",X"4D",X"A6",X"A4",X"27",X"1E", + X"84",X"01",X"8B",X"07",X"AE",X"21",X"BD",X"02",X"6F",X"6A",X"A4",X"EC",X"21",X"0D",X"DB",X"2A", + X"0B",X"C0",X"02",X"C1",X"81",X"2E",X"05",X"6F",X"A4",X"CC",X"80",X"80",X"ED",X"21",X"31",X"23", + X"10",X"8C",X"C9",X"65",X"26",X"D6",X"35",X"B6",X"34",X"16",X"D6",X"C6",X"47",X"57",X"D7",X"C6", + X"90",X"C6",X"E6",X"61",X"10",X"83",X"00",X"00",X"27",X"1A",X"1F",X"01",X"84",X"C0",X"27",X"0A", + X"81",X"C0",X"27",X"06",X"AD",X"9F",X"C8",X"EC",X"20",X"06",X"1F",X"10",X"58",X"48",X"1F",X"01", + X"AD",X"9F",X"C8",X"EC",X"35",X"96",X"34",X"06",X"86",X"C9",X"1F",X"8B",X"35",X"06",X"DD",X"10", + X"84",X"0F",X"97",X"16",X"96",X"10",X"84",X"F0",X"97",X"10",X"91",X"11",X"27",X"34",X"8B",X"80", + X"CB",X"80",X"DD",X"12",X"91",X"13",X"25",X"04",X"1E",X"98",X"DD",X"12",X"D0",X"12",X"54",X"54", + X"54",X"54",X"D7",X"14",X"1F",X"10",X"C4",X"0F",X"D0",X"16",X"4F",X"C4",X"0F",X"20",X"03",X"9B", + X"14",X"5A",X"26",X"FB",X"97",X"15",X"D6",X"10",X"D1",X"11",X"2D",X"04",X"D0",X"15",X"20",X"02", + X"DB",X"15",X"86",X"C8",X"1F",X"8B",X"39",X"7E",X"00",X"F6",X"00",X"00",X"00",X"48",X"00",X"82", + X"00",X"9C",X"00",X"D1",X"00",X"ED",X"00",X"FC",X"00",X"00",X"00",X"A4",X"00",X"EA",X"01",X"20", + X"01",X"7B",X"01",X"EB",X"02",X"06",X"00",X"00",X"00",X"65",X"00",X"85",X"00",X"A2",X"00",X"00", + X"00",X"C1",X"00",X"EE",X"01",X"2A",X"D6",X"E6",X"F6",X"06",X"16",X"26",X"16",X"06",X"16",X"26", + X"16",X"06",X"F6",X"E6",X"D6",X"C6",X"B6",X"A6",X"B6",X"A6",X"B6",X"A6",X"B6",X"C6",X"D6",X"E6", + X"F6",X"06",X"16",X"06",X"F6",X"E6",X"C6",X"D6",X"E6",X"F6",X"16",X"26",X"16",X"06",X"F6",X"06", + X"16",X"F6",X"D6",X"C6",X"B6",X"C6",X"D6",X"C6",X"E6",X"D6",X"C6",X"D6",X"B6",X"A6",X"B6",X"A6", + X"B6",X"C6",X"B6",X"C6",X"D6",X"E6",X"D6",X"E6",X"C6",X"E6",X"F6",X"06",X"F6",X"E6",X"D6",X"C5", + X"A5",X"A4",X"A3",X"C4",X"D3",X"D5",X"E3",X"C3",X"D4",X"B4",X"B3",X"A4",X"A3",X"D4",X"B4",X"C5", + X"B4",X"B3",X"C4",X"C5",X"D4",X"D5",X"C4",X"D5",X"B4",X"C5",X"E6",X"E5",X"D4",X"B3",X"B4",X"B3", + X"A3",X"A4",X"B4",X"B5",X"C5",X"D5",X"D6",X"D5",X"C5",X"C4",X"B3",X"A3",X"A4",X"A5",X"B6",X"B5", + X"D4",X"C5",X"B5",X"A5",X"A4",X"B5",X"A5",X"C5",X"C6",X"A6",X"B6",X"C6",X"D6",X"C6",X"A6",X"B6", + X"A6",X"C6",X"B6",X"C6",X"D6",X"C6",X"B6",X"A6",X"C6",X"D6",X"B6",X"A6",X"B6",X"A6",X"B6",X"D6", + X"B6",X"A6",X"C6",X"46",X"36",X"46",X"26",X"46",X"56",X"46",X"56",X"46",X"36",X"26",X"16",X"06", + X"16",X"06",X"26",X"16",X"36",X"26",X"46",X"36",X"56",X"46",X"36",X"46",X"26",X"36",X"16",X"26", + X"06",X"16",X"06",X"16",X"26",X"36",X"46",X"56",X"46",X"56",X"36",X"46",X"56",X"36",X"56",X"36", + X"56",X"46",X"56",X"46",X"36",X"26",X"36",X"36",X"34",X"35",X"45",X"35",X"34",X"35",X"45",X"F5", + X"F0",X"B0",X"BC",X"B4",X"34",X"B4",X"BC",X"B2",X"12",X"14",X"34",X"24",X"23",X"B3",X"BC",X"B4", + X"34",X"24",X"C6",X"C6",X"F6",X"36",X"F6",X"C6",X"F6",X"C6",X"46",X"46",X"46",X"C6",X"F6",X"C6", + X"16",X"C6",X"C6",X"20",X"20",X"20",X"20",X"20",X"20",X"20",X"22",X"30",X"32",X"30",X"32",X"30", + X"32",X"32",X"32",X"30",X"33",X"30",X"30",X"20",X"20",X"20",X"20",X"20",X"20",X"20",X"20",X"20", + X"30",X"22",X"32",X"34",X"34",X"31",X"31",X"34",X"32",X"32",X"33",X"30",X"20",X"30",X"20",X"30", + X"32",X"30",X"32",X"30",X"32",X"33",X"31",X"30",X"20",X"22",X"30",X"30",X"22",X"30",X"22",X"34", + X"32",X"30",X"22",X"32",X"34",X"33",X"31",X"30",X"22",X"32",X"34",X"34",X"32",X"32",X"30",X"22", + X"32",X"30",X"20",X"20",X"20",X"20",X"20",X"22",X"32",X"30",X"24",X"32",X"30",X"24",X"32",X"30", + X"20",X"20",X"20",X"22",X"30",X"21",X"30",X"22",X"30",X"20",X"32",X"33",X"34",X"32",X"30",X"20", + X"20",X"20",X"20",X"22",X"34",X"31",X"31",X"30",X"22",X"30",X"20",X"20",X"20",X"20",X"22",X"30", + X"30",X"20",X"20",X"20",X"21",X"30",X"23",X"30",X"22",X"30",X"22",X"33",X"30",X"20",X"20",X"20", + X"24",X"32",X"32",X"33",X"31",X"30",X"20",X"32",X"32",X"32",X"30",X"21",X"32",X"33",X"30",X"21", + X"30",X"20",X"30",X"20",X"20",X"20",X"20",X"40",X"40",X"41",X"40",X"40",X"40",X"40",X"40",X"40", + X"40",X"40",X"40",X"40",X"40",X"40",X"40",X"40",X"40",X"40",X"40",X"40",X"40",X"40",X"40",X"40", + X"40",X"40",X"40",X"40",X"40",X"40",X"42",X"51",X"42",X"41",X"50",X"43",X"53",X"40",X"42",X"40", + X"42",X"50",X"40",X"40",X"40",X"43",X"42",X"50",X"43",X"50",X"42",X"41",X"40",X"40",X"48",X"40", + X"40",X"40",X"42",X"51",X"40",X"40",X"42",X"52",X"52",X"54",X"53",X"50",X"40",X"60",X"62",X"70", + X"60",X"60",X"60",X"60",X"60",X"72",X"71",X"72",X"70",X"60",X"60",X"60",X"61",X"70",X"60",X"60", + X"70",X"60",X"62",X"70",X"63",X"71",X"70",X"60",X"60",X"60",X"61",X"74",X"70",X"73",X"73",X"74", + X"71",X"72",X"72",X"70",X"60",X"70",X"63",X"73",X"70",X"71",X"70",X"70",X"60",X"68",X"60",X"70", + X"61",X"73",X"70",X"80",X"80",X"90",X"90",X"90",X"82",X"82",X"90",X"82",X"82",X"80",X"82",X"80", + X"82",X"92",X"82",X"91",X"82",X"92",X"82",X"90",X"80",X"90",X"83",X"90",X"90",X"90",X"82",X"80", + X"82",X"80",X"82",X"80",X"82",X"80",X"90",X"82",X"90",X"90",X"82",X"80",X"82",X"80",X"82",X"80", + X"82",X"80",X"82",X"90",X"90",X"93",X"91",X"93",X"92",X"92",X"80",X"80",X"93",X"80",X"90",X"80", + X"90",X"92",X"80",X"90",X"92",X"92",X"82",X"80",X"92",X"90",X"82",X"81",X"80",X"82",X"80",X"82", + X"80",X"82",X"80",X"82",X"80",X"91",X"90",X"91",X"90",X"91",X"8A",X"80",X"90",X"90",X"A0",X"A1", + X"B1",X"A0",X"B0",X"B0",X"A1",X"B0",X"A0",X"B0",X"B0",X"A0",X"B1",X"B1",X"B1",X"A1",X"B0",X"B0", + X"A0",X"B0",X"B0",X"B0",X"B0",X"A0",X"B0",X"B0",X"B0",X"B1",X"B1",X"B1",X"A1",X"B1",X"B1",X"B0", + X"B0",X"B0",X"A0",X"B0",X"B0",X"A0",X"B1",X"B1",X"B1",X"B1",X"B0",X"A0",X"B0",X"B0",X"B0",X"B0", + X"B0",X"A0",X"B0",X"B0",X"B0",X"B0",X"A0",X"B0",X"B0",X"B0",X"B0",X"B0",X"A0",X"B0",X"B0",X"B0", + X"B0",X"B0",X"B0",X"A0",X"B0",X"B0",X"B0",X"B0",X"A0",X"B0",X"B0",X"A0",X"B0",X"A0",X"B0",X"B0", + X"A0",X"B0",X"A0",X"B0",X"B0",X"B0",X"A0",X"B0",X"B0",X"B0",X"B0",X"A0",X"B0",X"B0",X"B0",X"B0", + X"B0",X"B0",X"B0",X"A0",X"B0",X"B0",X"B0",X"B0",X"B0",X"A0",X"A0",X"B0",X"B0",X"A0",X"C0",X"C0", + X"C0",X"C0",X"C0",X"D0",X"C0",X"D0",X"D0",X"C0",X"C0",X"C0",X"C0",X"C0",X"C0",X"D0",X"D0",X"C0", + X"D0",X"D5",X"D0",X"D0",X"D0",X"C0",X"D0",X"C0",X"D0",X"C0",X"D0",X"0D",X"BE",X"0D",X"B5",X"0D", + X"D1",X"0D",X"E7",X"0D",X"FD",X"0E",X"0B",X"0E",X"1B",X"0E",X"31",X"0E",X"44",X"03",X"03",X"FD", + X"FD",X"0E",X"57",X"0D",X"BE",X"0E",X"5E",X"0E",X"77",X"0E",X"87",X"0E",X"B0",X"0E",X"9A",X"0E", + X"C0",X"0E",X"AA",X"0E",X"B7",X"0D",X"BE",X"0D",X"AD",X"0D",X"A5",X"0D",X"A9",X"0E",X"07",X"0D", + X"A3",X"0D",X"A7",X"08",X"08",X"08",X"08",X"08",X"04",X"06",X"08",X"06",X"07",X"07",X"08",X"07", + X"05",X"0D",X"A9",X"0D",X"A9",X"00",X"00",X"D0",X"FF",X"18",X"08",X"FF",X"00",X"F0",X"FF",X"20", + X"00",X"FF",X"00",X"28",X"FF",X"E0",X"00",X"FF",X"00",X"E0",X"00",X"00",X"10",X"FF",X"E8",X"08", + X"01",X"00",X"00",X"EC",X"FF",X"40",X"F4",X"FF",X"C0",X"F4",X"FF",X"0C",X"F0",X"FF",X"0C",X"1C", + X"FF",X"F4",X"1C",X"FF",X"F4",X"F0",X"01",X"00",X"00",X"C8",X"FF",X"30",X"00",X"FF",X"00",X"30", + X"FF",X"D0",X"00",X"FF",X"30",X"D0",X"00",X"00",X"30",X"FF",X"D0",X"D0",X"01",X"FF",X"20",X"08", + X"FF",X"00",X"30",X"FF",X"E0",X"08",X"01",X"04",X"08",X"04",X"04",X"00",X"20",X"C0",X"FF",X"20", + X"20",X"FF",X"E0",X"20",X"FF",X"E0",X"E0",X"FF",X"20",X"E0",X"01",X"00",X"E0",X"0C",X"FF",X"40", + X"F4",X"FF",X"C0",X"F4",X"FF",X"0C",X"28",X"FF",X"0C",X"E4",X"FF",X"F4",X"E4",X"FF",X"F4",X"28", + X"01",X"00",X"28",X"F4",X"FF",X"B0",X"10",X"00",X"14",X"24",X"FF",X"34",X"B4",X"00",X"04",X"3C", + X"FF",X"BC",X"C0",X"01",X"00",X"28",X"E8",X"FF",X"B0",X"3C",X"00",X"04",X"D0",X"FF",X"4C",X"10", + X"00",X"D8",X"D4",X"FF",X"0C",X"50",X"01",X"FF",X"10",X"00",X"FF",X"00",X"FC",X"01",X"FF",X"E8", + X"F8",X"FF",X"00",X"F4",X"FF",X"24",X"F4",X"FF",X"F4",X"50",X"FF",X"F4",X"B0",X"FF",X"24",X"0C", + X"FF",X"00",X"0C",X"FF",X"E8",X"08",X"01",X"00",X"00",X"20",X"FF",X"10",X"0C",X"FF",X"F0",X"34", + X"FF",X"F0",X"CC",X"FF",X"10",X"F4",X"01",X"00",X"F4",X"F0",X"FF",X"14",X"F0",X"FF",X"08",X"20", + X"FF",X"F8",X"20",X"FF",X"EC",X"F0",X"FF",X"00",X"E0",X"01",X"FF",X"04",X"18",X"FF",X"08",X"E4", + X"FF",X"10",X"F8",X"FF",X"00",X"F4",X"FF",X"E8",X"14",X"01",X"FF",X"18",X"EC",X"FF",X"F4",X"F8", + X"FF",X"00",X"F8",X"FF",X"F4",X"20",X"01",X"FF",X"F4",X"E8",X"FF",X"00",X"F8",X"FF",X"0C",X"04", + X"FF",X"0C",X"FC",X"FF",X"F4",X"20",X"01",X"BD",X"F5",X"33",X"8E",X"C8",X"67",X"C6",X"0C",X"BD", + X"F5",X"3F",X"86",X"80",X"97",X"77",X"CC",X"0D",X"0D",X"DD",X"42",X"97",X"44",X"C6",X"38",X"D7", + X"45",X"39",X"BD",X"0E",X"D6",X"96",X"67",X"85",X"10",X"26",X"12",X"85",X"08",X"27",X"05",X"CC", + X"00",X"20",X"20",X"04",X"DC",X"6D",X"27",X"08",X"C3",X"00",X"02",X"20",X"03",X"CC",X"00",X"00", + X"DD",X"6D",X"DD",X"49",X"96",X"67",X"85",X"20",X"26",X"06",X"0D",X"71",X"27",X"20",X"20",X"02", + X"0F",X"71",X"D6",X"71",X"C1",X"10",X"27",X"16",X"C1",X"08",X"2C",X"09",X"CA",X"08",X"C5",X"02", + X"27",X"01",X"5F",X"C4",X"09",X"58",X"58",X"58",X"58",X"4F",X"0C",X"71",X"20",X"05",X"CC",X"00", + X"00",X"0F",X"71",X"DD",X"4B",X"96",X"67",X"84",X"44",X"27",X"0A",X"C6",X"FF",X"D7",X"77",X"84", + X"40",X"97",X"69",X"20",X"04",X"96",X"77",X"2B",X"5C",X"0C",X"77",X"96",X"77",X"D6",X"69",X"26", + X"17",X"81",X"12",X"22",X"17",X"D6",X"67",X"C5",X"02",X"26",X"4A",X"44",X"44",X"88",X"0F",X"97", + X"42",X"86",X"1C",X"97",X"45",X"7E",X"0F",X"F7",X"81",X"3F",X"23",X"07",X"C6",X"80",X"D7",X"77", + X"7E",X"0F",X"F7",X"81",X"10",X"23",X"02",X"86",X"10",X"8B",X"30",X"97",X"78",X"BD",X"F5",X"17", + X"84",X"7F",X"91",X"78",X"23",X"F7",X"5F",X"1C",X"FE",X"46",X"56",X"46",X"56",X"46",X"56",X"DD", + X"47",X"C3",X"00",X"05",X"DD",X"49",X"96",X"77",X"44",X"44",X"44",X"88",X"0F",X"97",X"43",X"97", + X"42",X"0F",X"44",X"20",X"52",X"96",X"67",X"85",X"01",X"26",X"38",X"98",X"68",X"84",X"03",X"27", + X"09",X"86",X"40",X"97",X"76",X"CC",X"05",X"00",X"20",X"39",X"0A",X"76",X"0A",X"76",X"2B",X"F1", + X"96",X"76",X"81",X"0A",X"23",X"08",X"C6",X"1A",X"3D",X"C3",X"00",X"94",X"20",X"25",X"CC",X"00", + X"00",X"20",X"20",X"00",X"2E",X"5C",X"8A",X"B8",X"B8",X"8A",X"5C",X"2E",X"00",X"00",X"00",X"2E", + X"5C",X"8A",X"B8",X"D6",X"6A",X"C4",X"0F",X"4F",X"1F",X"01",X"E6",X"89",X"0F",X"D3",X"59",X"49", + X"C3",X"01",X"6C",X"DD",X"74",X"DD",X"47",X"96",X"67",X"84",X"03",X"97",X"68",X"0F",X"67",X"39"); +begin +process(clk) +begin + if rising_edge(clk) then + data <= rom_data(to_integer(unsigned(addr))); + end if; +end process; +end architecture; diff --git a/GCE - Vectrex_MiST/rtl/video_mixer.sv b/GCE - Vectrex_MiST/rtl/video_mixer.sv new file mode 100644 index 00000000..04cfd4ba --- /dev/null +++ b/GCE - Vectrex_MiST/rtl/video_mixer.sv @@ -0,0 +1,242 @@ +// +// +// Copyright (c) 2017 Sorgelig +// +// This program is GPL Licensed. See COPYING for the full license. +// +// +//////////////////////////////////////////////////////////////////////////////////////////////////////// + +`timescale 1ns / 1ps + +// +// LINE_LENGTH: Length of display line in pixels +// Usually it's length from HSync to HSync. +// May be less if line_start is used. +// +// HALF_DEPTH: If =1 then color dept is 3 bits per component +// For half depth 6 bits monochrome is available with +// mono signal enabled and color = {G, R} + +module video_mixer +#( + parameter LINE_LENGTH = 768, + parameter HALF_DEPTH = 0, + + parameter OSD_COLOR = 3'd4, + parameter OSD_X_OFFSET = 10'd0, + parameter OSD_Y_OFFSET = 10'd0 +) +( + // master clock + // it should be multiple by (ce_pix*4). + input clk_sys, + + // Pixel clock or clock_enable (both are accepted). + input ce_pix, + + // Some systems have multiple resolutions. + // ce_pix_actual should match ce_pix where every second or fourth pulse is enabled, + // thus half or qurter resolutions can be used without brake video sync while switching resolutions. + // For fixed single resolution (or when video sync stability isn't required) ce_pix_actual = ce_pix. + input ce_pix_actual, + + // OSD SPI interface + input SPI_SCK, + input SPI_SS3, + input SPI_DI, + + // scanlines (00-none 01-25% 10-50% 11-75%) + input [1:0] scanlines, + + // 0 = HVSync 31KHz, 1 = CSync 15KHz + input scandoubler_disable, + + // High quality 2x scaling + input hq2x, + + // YPbPr always uses composite sync + input ypbpr, + + // 0 = 16-240 range. 1 = 0-255 range. (only for YPbPr color space) + input ypbpr_full, + + // color + input [DWIDTH:0] R, + input [DWIDTH:0] G, + input [DWIDTH:0] B, + + // Monochrome mode (for HALF_DEPTH only) + input mono, + + // interlace sync. Positive pulses. + input HSync, + input VSync, + + // Falling of this signal means start of informative part of line. + // It can be horizontal blank signal. + // This signal can be used to reduce amount of required FPGA RAM for HQ2x scan doubler + // If FPGA RAM is not an issue, then simply set it to 0 for whole line processing. + // Keep in mind: due to algo first and last pixels of line should be black to avoid side artefacts. + // Thus, if blank signal is used to reduce the line, make sure to feed at least one black (or paper) pixel + // before first informative pixel. + input line_start, + + // MiST video output signals + output [5:0] VGA_R, + output [5:0] VGA_G, + output [5:0] VGA_B, + output VGA_VS, + output VGA_HS +); + +localparam DWIDTH = HALF_DEPTH ? 2 : 5; + +wire [DWIDTH:0] R_sd; +wire [DWIDTH:0] G_sd; +wire [DWIDTH:0] B_sd; +wire hs_sd, vs_sd; + +scandoubler #(.LENGTH(LINE_LENGTH), .HALF_DEPTH(HALF_DEPTH)) scandoubler +( + .*, + .hs_in(HSync), + .vs_in(VSync), + .r_in(R), + .g_in(G), + .b_in(B), + + .hs_out(hs_sd), + .vs_out(vs_sd), + .r_out(R_sd), + .g_out(G_sd), + .b_out(B_sd) +); + +wire [DWIDTH:0] rt = (scandoubler_disable ? R : R_sd); +wire [DWIDTH:0] gt = (scandoubler_disable ? G : G_sd); +wire [DWIDTH:0] bt = (scandoubler_disable ? B : B_sd); + +generate + if(HALF_DEPTH) begin + wire [5:0] r = mono ? {gt,rt} : {rt,rt}; + wire [5:0] g = mono ? {gt,rt} : {gt,gt}; + wire [5:0] b = mono ? {gt,rt} : {bt,bt}; + end else begin + wire [5:0] r = rt; + wire [5:0] g = gt; + wire [5:0] b = bt; + end +endgenerate + +wire hs = (scandoubler_disable ? HSync : hs_sd); +wire vs = (scandoubler_disable ? VSync : vs_sd); + +reg scanline = 0; +always @(posedge clk_sys) begin + reg old_hs, old_vs; + + old_hs <= hs; + old_vs <= vs; + + if(old_hs && ~hs) scanline <= ~scanline; + if(old_vs && ~vs) scanline <= 0; +end + +wire [5:0] r_out, g_out, b_out; +always @(*) begin + case(scanlines & {scanline, scanline}) + 1: begin // reduce 25% = 1/2 + 1/4 + r_out = {1'b0, r[5:1]} + {2'b00, r[5:2]}; + g_out = {1'b0, g[5:1]} + {2'b00, g[5:2]}; + b_out = {1'b0, b[5:1]} + {2'b00, b[5:2]}; + end + + 2: begin // reduce 50% = 1/2 + r_out = {1'b0, r[5:1]}; + g_out = {1'b0, g[5:1]}; + b_out = {1'b0, b[5:1]}; + end + + 3: begin // reduce 75% = 1/4 + r_out = {2'b00, r[5:2]}; + g_out = {2'b00, g[5:2]}; + b_out = {2'b00, b[5:2]}; + end + + default: begin + r_out = r; + g_out = g; + b_out = b; + end + endcase +end + +wire [5:0] red, green, blue; +osd #(OSD_X_OFFSET, OSD_Y_OFFSET, OSD_COLOR) osd +( + .*, + + .R_in(r_out), + .G_in(g_out), + .B_in(b_out), + .HSync(hs), + .VSync(vs), + + .R_out(red), + .G_out(green), + .B_out(blue) +); + +wire [5:0] yuv_full[225] = '{ + 6'd0, 6'd0, 6'd0, 6'd0, 6'd1, 6'd1, 6'd1, 6'd1, + 6'd2, 6'd2, 6'd2, 6'd3, 6'd3, 6'd3, 6'd3, 6'd4, + 6'd4, 6'd4, 6'd5, 6'd5, 6'd5, 6'd5, 6'd6, 6'd6, + 6'd6, 6'd7, 6'd7, 6'd7, 6'd7, 6'd8, 6'd8, 6'd8, + 6'd9, 6'd9, 6'd9, 6'd9, 6'd10, 6'd10, 6'd10, 6'd11, + 6'd11, 6'd11, 6'd11, 6'd12, 6'd12, 6'd12, 6'd13, 6'd13, + 6'd13, 6'd13, 6'd14, 6'd14, 6'd14, 6'd15, 6'd15, 6'd15, + 6'd15, 6'd16, 6'd16, 6'd16, 6'd17, 6'd17, 6'd17, 6'd17, + 6'd18, 6'd18, 6'd18, 6'd19, 6'd19, 6'd19, 6'd19, 6'd20, + 6'd20, 6'd20, 6'd21, 6'd21, 6'd21, 6'd21, 6'd22, 6'd22, + 6'd22, 6'd23, 6'd23, 6'd23, 6'd23, 6'd24, 6'd24, 6'd24, + 6'd25, 6'd25, 6'd25, 6'd25, 6'd26, 6'd26, 6'd26, 6'd27, + 6'd27, 6'd27, 6'd27, 6'd28, 6'd28, 6'd28, 6'd29, 6'd29, + 6'd29, 6'd29, 6'd30, 6'd30, 6'd30, 6'd31, 6'd31, 6'd31, + 6'd31, 6'd32, 6'd32, 6'd32, 6'd33, 6'd33, 6'd33, 6'd33, + 6'd34, 6'd34, 6'd34, 6'd35, 6'd35, 6'd35, 6'd35, 6'd36, + 6'd36, 6'd36, 6'd36, 6'd37, 6'd37, 6'd37, 6'd38, 6'd38, + 6'd38, 6'd38, 6'd39, 6'd39, 6'd39, 6'd40, 6'd40, 6'd40, + 6'd40, 6'd41, 6'd41, 6'd41, 6'd42, 6'd42, 6'd42, 6'd42, + 6'd43, 6'd43, 6'd43, 6'd44, 6'd44, 6'd44, 6'd44, 6'd45, + 6'd45, 6'd45, 6'd46, 6'd46, 6'd46, 6'd46, 6'd47, 6'd47, + 6'd47, 6'd48, 6'd48, 6'd48, 6'd48, 6'd49, 6'd49, 6'd49, + 6'd50, 6'd50, 6'd50, 6'd50, 6'd51, 6'd51, 6'd51, 6'd52, + 6'd52, 6'd52, 6'd52, 6'd53, 6'd53, 6'd53, 6'd54, 6'd54, + 6'd54, 6'd54, 6'd55, 6'd55, 6'd55, 6'd56, 6'd56, 6'd56, + 6'd56, 6'd57, 6'd57, 6'd57, 6'd58, 6'd58, 6'd58, 6'd58, + 6'd59, 6'd59, 6'd59, 6'd60, 6'd60, 6'd60, 6'd60, 6'd61, + 6'd61, 6'd61, 6'd62, 6'd62, 6'd62, 6'd62, 6'd63, 6'd63, + 6'd63 +}; + +// http://marsee101.blog19.fc2.com/blog-entry-2311.html +// Y = 16 + 0.257*R + 0.504*G + 0.098*B (Y = 0.299*R + 0.587*G + 0.114*B) +// Pb = 128 - 0.148*R - 0.291*G + 0.439*B (Pb = -0.169*R - 0.331*G + 0.500*B) +// Pr = 128 + 0.439*R - 0.368*G - 0.071*B (Pr = 0.500*R - 0.419*G - 0.081*B) + +wire [18:0] y_8 = 19'd04096 + ({red, 8'd0} + {red, 3'd0}) + ({green, 9'd0} + {green, 2'd0}) + ({blue, 6'd0} + {blue, 5'd0} + {blue, 2'd0}); +wire [18:0] pb_8 = 19'd32768 - ({red, 7'd0} + {red, 4'd0} + {red, 3'd0}) - ({green, 8'd0} + {green, 5'd0} + {green, 3'd0}) + ({blue, 8'd0} + {blue, 7'd0} + {blue, 6'd0}); +wire [18:0] pr_8 = 19'd32768 + ({red, 8'd0} + {red, 7'd0} + {red, 6'd0}) - ({green, 8'd0} + {green, 6'd0} + {green, 5'd0} + {green, 4'd0} + {green, 3'd0}) - ({blue, 6'd0} + {blue , 3'd0}); + +wire [7:0] y = ( y_8[17:8] < 16) ? 8'd16 : ( y_8[17:8] > 235) ? 8'd235 : y_8[15:8]; +wire [7:0] pb = (pb_8[17:8] < 16) ? 8'd16 : (pb_8[17:8] > 240) ? 8'd240 : pb_8[15:8]; +wire [7:0] pr = (pr_8[17:8] < 16) ? 8'd16 : (pr_8[17:8] > 240) ? 8'd240 : pr_8[15:8]; + +assign VGA_R = ypbpr ? (ypbpr_full ? yuv_full[pr-8'd16] : pr[7:2]) : red; +assign VGA_G = ypbpr ? (ypbpr_full ? yuv_full[y -8'd16] : y[7:2]) : green; +assign VGA_B = ypbpr ? (ypbpr_full ? yuv_full[pb-8'd16] : pb[7:2]) : blue; +assign VGA_VS = (scandoubler_disable | ypbpr) ? 1'b1 : ~vs_sd; +assign VGA_HS = scandoubler_disable ? ~(HSync ^ VSync) : ypbpr ? ~(hs_sd ^ vs_sd) : ~hs_sd; + +endmodule diff --git a/GCE - Vectrex_MiST/tools/tools_prom_src/binaries/linux32/duplicate_byte b/GCE - Vectrex_MiST/tools/tools_prom_src/binaries/linux32/duplicate_byte new file mode 100644 index 0000000000000000000000000000000000000000..f1dff2e906d91aa6738603764f875c8ed747b330 GIT binary patch literal 7356 zcmeHMeQcA*9X>k_H8gRP5IVPH%%i3ah!}^36pFgye855jNkd@j7`!;P6MHzeWxp;7 z?KCovk0^~6P1A(bX@gDOG^vw1wW`pVy0qb=llX&b+Eh)GN;^6kg{^dDC{t6s=ehGG zZ$in>-`#ufz29nW-)ghjgbsF5B8dFoaX1^GJ1bRAgYbyOqE@UB z%f%ujF|XkWI1mpCP)d>JfRsSGfxCwsPRdeX3iFUG1xg5%rL;SRps>8CQ2EvO2~quH zhf@j))j(J;^X*Wz$gf2{RH&_4UOE*|Sy7Z2CPV~Om5FO&4GS9xf<%-^q z$NX0UUmSA%VCCA*gRzzuH+H^Px3q3C`@I;#I^k=z^d3sbOsI4u7=|?(C|c_e#u8#% zds|bpvEEld6Z5l4^l7{F8a|bO+YsY?P#7v>v2u=n5OJ9_w z!N54EF(FQBOj;Q=I$A*uUNto)*G&yytD%OE@5)_w=4o^9(8RMfLX7053x&ebakDhf zs`G1MJO3yQ=FU0yP6$!hFol{6tETZ}vBE00Aj;^qD=1l5#g;^wckQyoY*Cb5xHc{^ zTNb5@U3*z#wlL};J|!_*8m%QBlb9`z`iYN7%$7$t5~qOc|F(blz1-Cso!wp0@ngv8 z#N(+w(W}@m^1lV)=GdIDd-wx%*>U9YT9^^pCr+=0KI=hmh9+z9eB%>)Zql~toy>~S z*HDMZjoW@oN}>8Fvn74gJL&v|QW~)3&N=q(n;1187Nfs;gnZb~U3Z`Mf{Q_{I>R(X z7GHFDnO3;`yNNM!uHML9_vF6mEHPJ(w3dxjobkXhhr7LwVTU*W^V@|23b1T`67gSu z8JVEv#vLO;TCUo?m2I@$gV18SDXo04DGiV`UwqnYD3OhL%&dl+%V)8*=MC8 zCt74Rv<#dPRL0glU@^J_@zECV7e>0hZZxdyVvE-aj}g!gYV!Z}>3`<@0h~$OSkYAV z-Aug>T5if_KCjy{iUh>ntY-*ujPBg9`>T6)?X4Hc;Y!hPY6ID*QoLgOG z+wZ&AbPR|m9^AZUy>}(^w?N#eV;{XB;Bp?dH)Pa5>Ibfc`_sNtDHQCj--7h8#m0_x6RbFairB zurLA(Bd{<6{|_U8S8{><(3)|+R{7p5gQRi}Cq5R$G>*Riyj@7Xgl|l~>*L?XHv;q} z;3d#m$h{DjTLxj^x#A{HBz%`{f$+W0PwdY@{IJV-Ei}Kcc&O)hGc{hd$tl=Jo04qH z4e0lQ5&fS7znOKR*HG65$R8nph1`NH!dd=)$iooL+t%Ftn5TAkPc~s@*R{tI!F1Bo z;A`}KsjfaN6F00@SO{Ncu-^>!K$~f$qdJCfxkx%Ce2JtP@dcXN>datY5%ndqzMgCh zpUttb@DW9WnW*rE2NSTTw3${p&qUIhSTZpO7|2UU;^eDHDsBp2EP*dcpBWjzvljqa z$#BpN3ST5@^rnOT5hEH#NsWXrWG2%YRHxK8Ldb;4V1F!x>XI;nhfms8c6u^khm!sM zk%XxS>%Y*;!Qnj859B=w0Owi<<}o}3!RMpo$@>gscz|`#=dXGsXx<6S_()>ug#Ksl_ zc?>5Zn#cWQ8V%sRi4MBnA0dG}nsDQz(v8Ws-sfoE&n!H7zXe_c(sag$$*+8(HP1nx&nR5xYn9#vswfcuNWss`>O3bS^#Uns0rBliV`IiqU*D-5SY z;5t`WD!HB&=E_y?MTPlRRqIn>?oim5unraGidJ{m3iBA<~>iZfr@839+#8K#R3x9t7Ci2~u`iFqOazeMKQhXQKTK@~cm$A=5!H>(uuNWx? z_UBE+b$@uv{Ci-1Ua{d6_2+r{9|G&~wBZz0iU#stlAc-x`^$jeEY??LFBiOD)#L5K z&HJOkI&gN|fc5xSpgo=Q@_T@}PqR#waLNA+*7Aqv@kfAp+euEPeW^G}T%7L;)c>M| z?*Zpk3ub%H0eg%5O1oRU4Q#zrzcP>iDKM{OgDA`Xms{36?X3Xz&(!}>;UVJU{F1*0 znCpY{&pZ2iVC#514$Qk=-ZPQk1gwJxkv+hCe=@C#Cx}qm%$V8UUS9|o_RZZLT}FG` zu5R4^8%E0}WMKVl_HGTZ=sP$y&nMR6G_6nh~RC5QkK@nukaum`(== zjYtCj9a^5=8Q9U*JU2)F)DXtD_Kv1NyV0?A>#o*rqdU;l-pa1ZKNX=&){uu#m~7nG z=Ik4M<4KzIeE6FYtWI`H_HteQHZh(Zw*GsJXp z9*S63w;dRef(E2XDD#25pf<>DJA8i9g^)?CL$M?e@b`RvlI)A4{zlY8 zJSW-uTT$=yZx~1t^|OCh#f|o>;?Y@gBa!J2rIVrARvlcI^-EW*LC)$2b(VwJwhYAB zvHsA5k4(Yl9Mj^GKZ`nzX){fZl9mA zohmTE@LW3iJnDt2c625aYT68^OjQ-?@-1qs)?uVgE!7kcr_)+m#FHJfMMN{=Y!=Bk zTecEyqDDf^q_wEfx(!prl3iLt#7r$77ilwv|00&ww9O*cl`$hC7Kta*nuu*p875dt z3rA6tG7@GCUQl)3i_Wl-5KCK@EoxF{hiXT1HE0Da^z?I*{e zEha~xOUW@f%g8af%gNEMg4{2JLS86DfV@bEAUOt7HF+_7Cx_>C0Ois1zq6h#Kg^vreCq46CPtWMv2OA=L!1D+pxw4(CmhgG6rv?sBq5@C$kZ;4y z2m8#+Mc;E*5D)#?q4I|-fW^a`*3U9z3Xk{#EXy5#`QUD1-Z_;WYRKN^_nI?%7Z>-I z_8*7eyV?T2UB1A;(zCf78nEra1IR!7J}Lpr9`N-F8}uS7b~Oj8v)cmIB2$^KF75xo zq3G8C8GW6*b`IpFg` zKQS4U!?`->tP|$>Xj*qz5aH)^CX$`AHEwlif75C?msn!l*y~Z>?`JpK0yT(5F@cy! z6390P&DRrD?gDYSr8XNhl~yg^OZ!{scw4{^r+sj%hFTh^WxY!a*9fPU-(sHjx4S@> zxIm8q^k#El?q4bb16M*T`84o1wgqNPd8RoqGgxL-`rYc3Ghr!k=SK6XUvopJoR7+T=(T>2}p<8Vjv zG!*nNM1}LA@pa~ma;0wS{rEGRN%^6B6yVS-ena^UaOz22qU z-OWmXPM*{BNy{P^H!)>jb70|=eaHJZj^lqlfLXZap(~{szwKrp+Mr9-_Bf==s2dq# z&;JMQ&UmKWJ`XF=|9lqPf$opFdcqBqQ{@JNI$a?51FQc$nx+!;O_wJ3LmB!vK=->q zT>YIs9UpKSq%~h# zyL!NYf*l7>Vvn93s_2aeYWnt<2QVr9 z$kuUL$ld!ZLbHcG^Uh}8${woNuu;AF;K|8j?0tB!w<6&1A^*O4nEU+fnVfmye&%Ak zvnPGIWV(WBhsrNXHm#n3cu0rn->-^qLk+dUOqK_jBp*4EdB z!tr=DF`-1JQ%j)~^(~%9mJNDKIgd~-WXz6qi5vf93Bc`N`w2|mgwP=SXOBGYs07Pu8 z4qtQai0Yu3#KSbT4lNbTBxqNQ1{uMsDj6X5*@)#kpSP5koB=?QXS#O*rzro18u}=g zYXN`gU%4DNO~rWY>;~TkehmCu;3vTOw;7Y?)>h%!=J!l5_WAC@a;BiH0(3w0U;qkH z;$KoyynM<9rmtHpyllahvja0(-vA22#zq=#Eb;FwSTuQ(cm1T7pog2oO&}9*i7>cT z-&j(7r?;`B^bTKRNm+K%ijtaw%}Ve7n| zKL5p_%R%*^C7`vS7-$RV4$ys|$3Xi)he5A_Y#mFRn&vCPHSL*%nYpUPNQ6^Kr7lz- zx_VY^Mi$PgvScAb>7GtA+zxK0EUw!*e%ncPiBKYGYN5tO%VwG3j=a>7$b{N629DH? zs0dNg!)aZFqCE-dvp9}jWz7~Xl{S)zF@lP^lolu6%5=r?+0RJe^fqK_-S~|`Kvk08 zutZ4H)mSRrsi}GtEp17J_+c&$a~8WLf=Z|icN!6xOF|8PLQ=P-r#%gHB-z=CZ*g|8 zJ_pC~rW|v8&hicg1|Y|Qoj4wuz6|1V3vu$U11c2c?PP!ZsYQW}y9;BJ->u{+LLO-2 znjxRgk1vkty?K2c+f2lfR)9FJX_sUD7;zwueK3jPnCE#u$2)ODm>WaLa8B5XSf-62 zdt7r&KZ-^Hl-YLKp0pXndB8m9!cpKhAy2z3qi;;Ng7|fvWt>YvRB*7``iP^P1=%>x zy&6<-P7=p?ZsYDop1#r!=l&j4IPW45$8;yi#+?A}1S{-LBFmVt=m+^?>f=3|6EJv; zLOv14bU(<}$F*iJoZ|U|oou@gqJTIV7vPQpS4|*q$NLMX#?eRpZ#i&Wn}>nB4rO*ChBN@O^<9J0?Q4|r`};m{ zv`@P{1#kWg+=r;Az8Vk{aaYQm^}{+6-wD)Zr-UNJC$<1i3=_HIv5Sh!5f?cA1(eSM zu@4+u9P>_nLooUWM?+g5VCN*RM=Z2%iCOE8C0h!(zF4wlf$NAR)4H`@STY7Z64wPw zwkCl6PV>qY%bMp_y@bj6Y{~3}_0F_pzHzPjX~|rnFuyPlEg6%7a{j&L6?}tR?{IRj zz+^x=iuptC<$WO}&J%L4j2zYz%m+*6Q?bUqCG(Aq_c_LoC0i>t$FU{zO)unlwPb5Y zz;S8G7n8}ofhBWCAOy#mC6`NCUduqvD=w9?{o}>T;CyaA@j;F~=4l!+9x+X>9kzcS zyitNExBc^ACo%^zjvFMt0P(pVvb@D1+g~cygY&KjpQH!&b?`0+-ff@nyi$k#9gqj| z@$+C*-vilc{{hI`^YN$sUqZGM`|~0MyFUW`c@?s~m+@eS^=DW8KOu8IgTdcR#3VS# zJ1`un)1dz%hr@h&S3pkX?N2M1EWQfaj=zFiddpn+4Up~UQ40UsUG*kpuG_Rf4dd%p zSADNb{)tQe1!Ug5Vf(2C7mEFmZGTGP&rt_n0p^bmnf-YWazlRnOf4uE!;qc#;k=GH zPrTxiuci$D!(fb8ldHbXC2Npd^7a^yTOix>jqQ1Xk@Jh=hxhTiUG49J?2PBVkauXSayp~1d+SVL9ybL&GL znyGe0R8!9+Hiz1~1-G=;RYjcR^7`VKHk#b=T9+M1D{6&hL|%v-Ew0I5ha6MFn~~0f z{4*Je&!~CV>+P)yHirRK!|KsnD$FcjOel_kP zrTkapYF0OO_}YVQjltR$UtMi$Yg@>-D&Pxtw)&b{eI*suzLvK7Ku&CIbf#ooS;|fFpd52@&k;gTB)UzK?#;n; zC`W;iFP-x3mHECm4BbpoIFssQFX*WKJh(glNInPnse*6s+jieXqTKfAB)WASpR(Im zS;!8QWO~!Y-SmjNZsNX&kh?Ppqi5>4b(ds%`maY9*pm*ZYyXse+a8GEm!99(uz5Ds z@}i3m7`;~+nk7S_)q9c=++B#Dt$m>d$cxI|e>U<#cmRL>Dr&wbr34gv zKCH$Mt3iUhYax-he_{+uGCMgBd4*c?`?~h0Tg60b%D(^j2*!@x*U;OOG7FMzewgGV zTeJ;&RLD9v#XopqTEpfKVwBJYbW`KEei@l|{d5Zw$Hjl+QUE>M-v^N2xAk!Rb$v${ z0<&!`Nw;fsA?u$WO;MC_*M<-hOrZqb{UX6ZN-zqThTbLlecgZlX#(&UE#0={_Ui8E zyN-YD?H}yT>pu()oVt2zm1FxfE`*%Q^ zuH&AqeVxDBZ32=1QrG)R{FW1_Ob&1Di{CPx_!tZ=LRHMsoTwk*)|WcnC$1brymsGL z$Xhkt$_IBHNl6CEcHj^)>Q6!w0CB<)32jm z*}Y^3#Ol8(1vNdJ`b>9eZ%^rtt$mlzg1+fHDRL_!x3w$X(=+>nM7N~3TfeC%d1u!? zr8|^qf~319Q}17lxbrUE(RuLae^Pr&dk^T;d~6Rf?SBi^u)7!K>Pevv+U?!VZ)m&S zJX6%rZr(wWT?1O6X9jhtt?%ve;ugQ<`(V^Fh8hb^6W#wI?9XnB*%o-`k}vr$wfYNh z#Yd<;sVTR5KN=W79ghXv{~Jm|y1-*bBZl-J*_!Qzye)C-zYjzQ45FeIKKkyz1_rv5 z(Pr~Siyr+l5F(!Ppwww1wTDu#Me3tJp)@GOR{-=vH4YeL7Kpq*4t3DA-*fbV50Uu; zz>toLcmn$0j2H3OBfgjaE$RMq*YUL7zC5mivrrZv)My~35c0qX5Ca{GluDB13{tS} z$G0BlDn_XX4jBX^d=91`CPGn5GDq~(WTruS59-CVT8i#O|Nf_-c@{LslwQdy z{ba1}2N~2U^i4~a9Y7$QM)_QY@Ih2IRh#wKbvzx>nP{?)jTb z$RKwXDp3cK51CTW>VE-R>xyXCUEJ{*>tKn+|zK^`+Z2+y$?Bat-K7BeDVPV?>qau6Xt~+=5O2 z!8Hy7QrlRi+(LQNNS%aOG|O2sV&Kq2U_a2cKl73=J+8CaJHR5;IQx3KWzW8rZa>;h z!z~T$Pk|vO19_Z!;K*!)qDyCw!L9Rmq+2pay7woF978LR+hfR$kkEzwnLIw@ki}7gI?s8Pq?@Kc0-R6vzpnkW_6d6h(f1I;qlaS| zYasp)KSVaYB(t!`>^iD+{li%2?n&PEY!Nao6x<8FJflJrH*Zg&PKJ&O_9R&k%+Gh< zM+(k8OaWarE# z6LI~M@N+CSqP~`N|LUTp)!qBLj+ghuE<-sXYx>rM@!vX*ymr?Bk^f##r9Shw!ML9F zrgo7z^SAL=bRn+m38kygGxM3wSI~v}?}t`x?dv`ezvU&8F?nsz3`+a+KdQ=e-E++Y z^wdSH)B4vySyAn2+B{G9TpfLw`n1k-q9Ue)uBXIHqw+w?CaNZyL9wPcTMw5-Fvd|xYxEKrk9+LQ>m**6+Z2IYX-+lS_yWWp^ zgn;;Oy$;gd6vW&=VfPUph~Lr&EcM^b|KwC%Yf+Z}phb51X_G=Jc5C>ltEl;g}0g~mvgeIR&b$=|WmzsH>=e!vtWc)UtRYS@PJzh+{UfH%} zztw7}Qk`@iwTfpZG+O+Y3sLTErLU55ih9+_V4FRqhj=@b?vH4K9lKxUh3WJ?(vN_! z2R-L)9f;pL5&8CX=v&{5-#VIt#U|O%t;ygI>8vtefg;5}P;EZM%N?T?>s=psdwxt% zsHp1$Unto1ff*V>f}&Y_k;j43BMg82G#`zBpy2NZHUSFxHvbyFw}HvO-uzcet9;bm zdF0rn_y-ZsK+t(fI0hLYGPHuYXMlU>SwE$=-nQgO|83xTEWO7&`KirlGO&58d&v>r z6coD!v0>4#pmG0bCpF2hVOt}!{;4WCRuadjv@xU}XjWd8#b!@ogp&U9pWH@L30KU4 zl0E|1(c{sRbaDWkyXfMO_V&JBt!mchbLm05^DRPOmKLML@95jt{hl1pm*)3XBaH_` zoENn54+dTF4=zaF`d%m_{=tLWN}|*95BJRX%zSa3Tbpmr{AJM7^*9Ve*37qp{rP>D zd}-fcdxPGBXI0D+zlQn1tjzuxnDVao&2`HmFjZ6k#i$DOqq5!P2#A01P8YxRCgTRv z0kwZ4lpX)z;r#cut?;HDi{=WNHS^7m38aWLW^{iIlX}>sA^_+kf532!ah*Ryt%ZF^ z&wt4R(O+m@Co_Hp)!+R%`42)PVIw>epG}#PzV@F0LDzoMa;W?adC}vEm3}v(^AAIG zj}*O^MDNB>t2^oww!%t5b=tqiN_D{9k7vz%GI%uqFmmZWG_=0Mx%DeDC*D2cOG&QoLxbCgH;!E;&)`uHRTzy@ z^QqBV8ehCaD&~1k7J9K~Stcm|{@b4)8_UU2zZc~Xka@H?qR46e>jn7|Uf`a+o2XIW z3(duYwpBCzTLsC~%}-G6cg7#flG8FO^%KcGOZBaXJKa5VVP-<v%T@xIKOhi%Jm=%-3UnYOG`cWh-Uo+|p1EzA(tn{)ysvXN#G;U~>4TQe%J>H= z;fkmxsH1ZZAa&CRO9@)rIUSI;>4Rc|>N+O^(l>ojMNqIa4G;n~p`=Y8ghFv$ujg(0 zAZo3vp||^mV{k2C;GqXx{%pI4q>10!j@*U6>QQvtfs~aZp2r@oMx^M(Fa61$dU6CT z?QTyV>;V;MWJB-3Ar5Y<7ys$0DdNqGI0i~4~+W`e?p4w^oYG9Ae70|O}qbbn$XrIPOZFv-Z`Y3fCqY0a7G zxUz6f$^TdWyZOKG?%(_`66)`VLf-Cdl9!8dG=zG8Xz$3Ml{{8~*kiB4KS=(Hte#SR z+Y-GyrQ|}4A;wBPqeSVf?|@N{5S4vT0V4J^1L`Rist?>0;6z=Np4d&L>@I!BcBP@# zpPfVPzFx>UkdlW0Dn=*HT>5q%WA@i-@Vi)lOZe;~9m)42w}F%_5cQ0C8DUbcmqOEf zvO|QLJqy2R-yV&4{U;((KhHxoJm`8RjV9AE{q4ELg!kzso7*xZ0x689Z9k8v@9qP4 zv}ZC5X(%%dJmR`vKx?I;)sjKFkEHgX7QluoqrXpOP{QsfLS;Q@J;}V=1t1esKq2#P z61jT@|D9_h&j=a1UjT;KQ#O>vBWRd`V^=lM^JN+r2(dnh;)cp%+}UR*=M|D-RmkDc zm>zZJ3!UC$<#K*u&U`WC>wdgv4*Zo|`9(e2CFk6F=9}FMxUb?vl*r~SiH^O9)O)z- zhmQSjxaY@AOjklB!9;S2Txz*Gcz@xtBj+X_09oge0|r$v{n;61igq}*zgN#ex2V6k+Mlg_X1Eb=S7?OiwUn^HBi4ovvAyq}Qwez zbwPi^f7w6d7=JP@Oo8D%_}75}a*Odl($l>#n)F9u9{89aA|N{YJA!oRIvghJ^kW#J zk4gGP)c=AS@OK14{-)NowarcS{`OkDw-1B@LI3L7*81i^kg?{bRgHCD&d#5jQ{UXo z{0r9ls{)Np9iS<0uI=aubf6BZH?)Ro*Za=(P3Z77G&KjnPu$x&L(wd_ieV+dq>!(z zJlpL1t81uK(hE@Z}n#{$31QR;4CNxg*O=z6#^JN7CArx^o06YR01sgkC0<9rm zeOpT{C^-*bR!PO8qO!%4!_gg(v9q~0*c95}%c?G$hd5TTHV|xRZd>OI*0weVtfUo7 zORMIVS6noi)vU&Hhd@VXbI8}!;S063`8rx^o0}2h3n2pSh(y+bdSBL(#U)lM#%kI^ zwavcfwvG;8TZ6Bosj;=Gp$YX?7w~1(lvh+&Bk#)EV5sS&RF#s7v3Cj!SyB<+LgT8$ zbrr6=aV?@c&t7--bXt%RYHA7i8fu%GJA;99qghdXJtXV!O=$P6uI=!(w)vV`Y8wOD z9f7(~Q(G(Z`Ia^XL!GtF7j_1M8+byLp`k74n^5mtwILMf@YRNVwKf;(8a|)ZO6?ti z&iXb~OmkaZE%Bp8BB8drwq_sdvx5*5>T}READd=XQwTM4S-_%gVI6EOt7AbH!cu~I z){KAjNAsgim4!U~#m~prz^s+w_`Lxv@uMG7On-jzJx1; z>;K@o3D-Ti`fwe_bsX1+xYFvd3ub2K!qtoG+qiDSbvLeuaP{GO3fEy=FXMU@*PFQB!}Sp^ z6Xj0Cm5ys7t~^}l;wr&KfB&zPb3aPl4D(+MiwE1&TrKz1BWrjp9CwviOjT$$Ql^7-3 zf-Pjfd1e?&^Y!XLXi2LWS?f#J*9F?i5<)uEEt{=ZHwOaktW2*71Th-ch5}Y4vP!+C zxdWmvt!?fMuuJumGGSlWrIkk75LypQk1Pxqi?ITXs2IuHS_A8wLhL+1je!u2g0;cM z4mJyL6Y3<;x|Wq9++5ezx|U-YYXVG@h1&LZe`rHH`Ud6$gz4;n#A5Vi>@w!Bt!t@o zZe>>^)Y8%D=NYkG%wH!$A2NRftpdb^U*W7#{1#S(a2xEy9f}`g#2PkF^-CGwRsEf< z9QRetzpkmZrS{7h@gLJ_SG5I0?3Wr86|s!{rzZHnpf%KC90mVBX$>^zV1L#c+JjB4 zp$2wLYan%F$LS7=ziSQapzH``>NHFfpDB7vprx*T1J<#~Y zx6l@QCBnPX!Z6LX`%=TOP54FNe?<+9+*HWYaZSg3+1LI>JO8g})Ke$~z5iA@y)IIr z|GzGSgb?xTeAeQ0vIW0Y1Zg<_39KC!iO6=i!_hMR!YNk#Uc_Tjqx~oNZ_Bsh4%bdtoTAKzI|j!`o|Yp@hrWNX+z>mDy(=f;!B5=|Ed*M{7N6z z2|5@E`JZU9;(d6P;fR*y@5FpTFr`-=-x-pBH{2*9{t)6X8d|=uTk&}l3)xK3V4RD{ zKkge={I0A*HqF8RlY-`0yZx1UijOD; zEO%9BQ**uetf~Ob&g6lVjT3C|H>W z58DV`zZMB~{Rfm>cXNDXYQ?l+E}gDlfMzoMrOS#-D{IOs7W=D8iz}*1Sfx5O>Rm*+ z>?wXR&34skQLjNU)C@<&+~!(Ly4C42Mt6@TiWyNekzCC%!yK%~9rf&}M(Bx};c+eQ zY*`fu!X+d;c3^XkWaAB|qbDMoo0A7eEr{~DC~Yz`^(cRF#p0UMWi{++Rqb*A4Eef> z+whdPJ|uNOHfbIomTs|{7-F^j3!x_@PmaOtk%CQ*Grbs*6m3Ge5Ls*&h+iFpzf>+v*J zAE>w7u86(E-H*D`GM-jg^hITh=TuabGd)168$D-vO)1mAk_82dzKFC@4^oeaE)hTn ztpZea9Ujcu5Y+t{w0m@UrAW2zL()FQCA*yHgQ_9A67PVf=omwLM|63`;(7kcnkr_T zgT*H-dPx{jKzT-2F0Cjlf#}pTqKoGjRWbD^)a7_erruAfbUg&+hCJ0^q(1RY0^rqL zJddfb-wi<5HxX)n(c+TwQl=g!UK-Cy5KU30Al~r96I)bM27#)JmX`X9s!EGkyZUwa zW2iK)_&;zT{X3h0<}q^&?U(^QPI$V=U%36mS~Sa zSHpW!M^0-02<#L!s+L z9zW=<_!2kPHBGc`je&8S;b-qZqbiTb|8 zny%{3Rn^kPw2GIGa zLsm9d!pWS1sd*Ak1>D?F%f-x>xHRC}*0#1Wb*jXS0tW9oFe3BXp#BAtKuZ%W!gNWK zDNz_dF(6CiM3HbRQ_uF+qaM|aEMSmfYhWFQUoTlFHDeZwp-LqJ-e)uchb%aXX+v5@ zE%3gGHq$DHi}@Z>>N>?+Z92ECywqycWc6C_Rd{paT2x!Nx~UbqyF-f0LQOQI!*xk4HuSry;ltPx=U(nOQMDYV<5%9}RBq|HZ24za&AAdp^a!EJ3e(6{Y>X1e0B4k}4X6mHUIlrnw&@qW_X$y89rBaYTYX_rEBE zS0tF}eucn4O3}02ej@&p1kZHuBJfoSPH`_H@Xr#=abHVmUz1>-`%239FA|*U&L!f0 znbCCjQi?q)!2IZOr>? zyrn0DG+`S0{kz_%m~b~8mS73^=sJ;|M5E50&Q7TAggMwIVd<2aAkDDQsi=eqor;#A z)Tx*R*;9p1c_b)xDprD0r{W|ibt+zh$wGU)34PpTr3vjxkg-yG5+x|LCrJt^wI^AE zQhQP)D77b5f>L`%NKk4|ngpfxjFcHk?HMIOsXe15D77bDf>L|NNLEsN&XAzgp0Tok zQhR(7tQ6WaPJ+vX_KcU{N})X&GNaW(dom^1EVO4r0vQE0qun;zgR}w7tWHd*Lo4h0 zB_Or50b{ioj;q=GYH`9-qz2XWav_8l@k}j|*)SKqwz5oUX#$yenvM)Mu5%Mean+18 zTaIuBq_Oi7UgIJ(;nx~o!W2xc<`P&jHRaX*;-d2MIYq?_nR-_8cr44(^(_1*D(B-j ziKbXdq<=hwxDsHK6&m?!D4r&BEM)7FuOZMWw&IbZKe1V@`x|0TV{%(hU+rEB{y`!`KcY!w(s%YL--%EuLFZ z#7bN@xf&Bu*>$U!>t>heL(J9OUWEl2!L<<0^&QtWygTT?mION1gxcDf>lTSLfvjl? zVJvjrDp4L+{kmn$wNo-(;IIkJEwD>_3Q`vZxc#j)ZQ zuIp}zEM!_lTeyDc`W-c+1Ib+bdGqMHn+&_D*SB@j#AC!#JijeovWV$1(bM2KOj}yx zFI`kwvs?rhFDWl)3L(p&?EF5RX>_le&UAh+UH@rUI!3eB%7tzJ@I!$uN757?t9P+c^) zw5Y18XgM2AV6h0NQ+P>rX;n$-+_J@`C2R~K#N+fCB6ty%c`SvcwLv}!5pXVWI3GUer^^U#6=16*^;1h}ZEdLd{8=bGh}rGx+oJ2exE zI8xz;%%gK}h}2e?Fhq?~qVZz;WJ~JYTh@a{*DuF!qH-&KlLr0J6ME9U_yN`Jh#$Ql z!DxTw(z#2SIfBjv08mCi8g+?u-Mr=xxToSVguhrfueEKgze6mIXrc!hbH_fAjaiPV zl5XBIH5FaRk9X_z!e1yKnle|}hRMCJy|UE8%u|kIkn*)Jt`Qgv zU&?%CI)=9}4x_44rqJ98kIXftbC@ztS!}I3sR`g&e4$%;9eHW=g9T@JYG350FzS+I z7^jrcvpB6M2+$%7EXQcXu=|*sk6~K=2*$?OU@ZhCe9X;3vFrj6jdEaf4rnqcoGBM4 z`mv}FOD6+Z>OhM+{P4N@`Frt#JU>>h_*XYIVre2%zON|C6-exBD65>$l)IH{0ATc7 zimIew5(SU}(PY+lwl`xDPAK4SZ^uFdv_%I~y1?Ndh#g;BM*ubR_}aA;B&@G?Z8KB0 zD!mxyd`(RG1}E^fGUZB+o8UwAH#w5BA+m{95v0D_{$#P_214JgDCC@1=?dxBrZF}t zu%1>i(yBd*CgoMPvq=q|tzxO5@*RoOCpBOW!<1VjY))#X2UO)&?zLC9dnSbkUuCCq zFG{0gI2^EE)(+Yz{$(03q!zsY_-Uj&20jPN{6Yl)chOU`@~82>1_klhZd&7*K+ zQFD98WyNhRP;#sSqSE||(EW(cl}X9z&Xi}qmIy7}{+*3EO|2z-EW5B1YjT+KYjU=a z!ytE7Arj?~Ci?km6y*pxH0h|0oCb1h!5^W#La3Vw)f&KxCSd+Zjs6Q@@_r84--LMY z;8I?B1trh7!0g{6&V_!8Gm%ap*qm6%I&djW(IM@$@z9o$h@PH=0Gm1szxN{g1tN)7 zrhp{hg0n-2%;v0Sd>g?9Nrh}B5-DdY(;fg^j;OQN1CjkSpsxeUegT2+Q{ayX97JH+ z&k=Z!2z!a}4M1n068N94&xU|!E101y!ZIXh3*5k4U~h6EdkR-RQv3{(okN{kxsj@2 z0O@G$k~7gyc%nl{@H(zbk?0*e(fuM(0a^xbW&#wY;Hw~U_s60}0qg)^w#bxlH+$86F% zKS<9LaKR)h?fLKW$k8q@q&$~|D0Jfuq5}6Ku_`D+@s%QhDmaVci)Ha!D0wN(9f9>8G&=FxmwQF389VVTM(k)i38g^VyTP!&{HhGr55i_6fxDg}nltRWiSsMR7J z9VC@Y?aGlg0_hbHJx|d2=XhDcVO-X2|LMdlC6iS&Y*cW^Tg^JLn zVU#FucqRHI&7t^Dtu7Ioa&jG+?a&cJqeGHrI~2vxUL}k}TMUg3Pl{-b^Z6TMe|sIx zL6{PtuAms2x4n?rQSI#_vVk-fkvbv^PDd-Uy=YUF(K}fERNjUA<-F_ky$!z)i!A8c z1Km_D_Dpf#O-g5IJ}9v!UWT)uaG5JkRpxbgXS76yJ}8*qIKo z7s8vZvW=%IHVzT&=xjfILepxNYtstZ3<&b+mmR2L*}-R6X7Fj378v}kCeudz9aU%W z7ra^%H*DfXuGT>j_KRGjT)bY@HjaS-bLlrzCK}gL(naTyQq-AkKz-^=cd^ zXjrF_aaQsXF2ig1bt|-e(Y%X(3ak)|l5eKS*<}0kG1*Tu&Pjd>+7r#^QPQ7Z(NI;p zj=R2%f@I=>msQcFt@T5rXUb?j+Kwy3i}Ur&I9JA);h18)i<*NMdmYR;PsVzp#p{cU z1Hm@(uP|eljPXVfesN*UmQl%;vv_b}jPsMJ?DADlL@YBZcsavP4mI*A(xqoWA7d0l zJn|`H#sD-L7S&Yo%~1;j8%pRcvvT1A;9Ytpem#67T8R*^Xija@RRuZSdYf*WMQ2h7 zEUv}Pt?VQ;wJeKOuu6PGs~`PMPPJDkQxKuN3zE1q@$93lcmQzRavr31iF+MU%8JDZ z#<$b608_q1)bZ_jZt>p>rpRXk5Z*9rzQaq|%UM%b)J9-WE=U%EYXZ+@FXe)#iv*t0 zUakP!^#q>RUdl_|Zn8uYoEEBfqbvUk;YX1^=}`obGU))n>q&?C-Aw*H?%g0rCMI_w zkV468ko-=_sH{jO!cjYQ>ynuCExA^vr|>U)tjSrR-WodC~K zq6V&`0z(Kkn%r)#IAsMyR+MzA7-h;>0W1c+l6x&UBW4u=c>)-NLAsgdbW`_p$}<4t zu^RI*VrytqF!Bi;=6Q1kj!xkk>Oi^RkueFkx@o=UkY=_3fJAzcB$2;fsG zMFB4{{kgKOu3qT*~pPjs~ksC2^pc+y;4S6FDsCEE;}rdnS>P8Nb{8D zP)9xXVvtXu4iA6-$s5Gb@+yZ=p}R?<=OodTAw(UWZ5GkT+bo^*Ru$~^~_1&dKL({o;iYC&jLfPX9@||Glgu|GXdQ7OaX`MnLx|+OyLOE zGa;nwSp)1p*E2y5*E50A^-MwA^(+9(^&E~0yP5a%W~;`MfiUhD z92e<&rnKDk%mdQ(OyOZ%&xEEHv|P`EjFu&^O+Er_*E6TIT+akJUC#tdUo*L$9iZ)c zCY;mtZ0K)75nT#B2n?DuxP?ntOCwb^TQ)fNZYf@#!s?wEqoTqVN*V#Cc;w>+9l{*t zx6yGDjl;u%mLr6G220V%o*G(mJB$#m*HhV#Pt^zsNmd7%+p%)%^qC@BX#NXa3n0(u zWr{TYv>7AaVT?|og$-ziG)5E@#)v{>jQAbKi0)*J_#MWG?qrPUE{qX{gfZec+ZYif zjS(l|#)v|;F(SY=Mg-W#hyXH1oPvyz2*4PL0E`hQfiV&Y7$c4#VWtU7$X9uF`}Stj09jAqi|H% z@a*T!HrN@Y?S&^AVd za~h*T2FRuO>#<(59xp89dPgNmNyNN~dgA@KV0O-fiEtB5Jr?jYC5fVGdW^Jz*2uIY zdD=eNi;*@+X?e1dRx(rA4tqzcGWK4YMH^ZnOc=X|j3mp#Ebf#hMe9TBL;Nchr)^e5 zds^snLlo8W_PV|=L@j}+mNVx9vQ=!^sY+ZM5?f_YpYbGV?;KgkDoNu1J@Ys{`sf$) zI4mKcX@$dd5@?xD3P+euLVPigLnX|yOefWd({vK-Fr5z2Hl2iXnodJ*ZpWS_HS+_S z(qU;kxnO=sHfyjqXf&cs%NwMPNC6n72-7F`$SdO%(roIsSD@P-0L87iqJil4ZfYWJ02U$tuT6BC}yQP3`Lsm5b6S=C%iNLA~mANRr zw)1@$BDdcUbI^oS$hb-9Y^OV|+=yKb8q6+D*ddcL8cIp4IhYc+T@cdOZld%X07QpL z;Zvn|+t`9q+d(U6V*W#N%>!3jnI0xxTUXbN<4J5%k0jMWiiH|v>25q#OIH^RS*N?5 zUSl_HbRp})5y+pHvD5TaJWc41MZ@yZjyB|Ct0XgqY{EUrguNkG#OSX5Xd7(E z_0n@nh8gBy?>0F*YJfBG7{hJI6>PlWbb~hJHejry4Y_XJjNFiWJ(wDUH{@F4$_=?v zMni7M6`%l{_;#Y_8*&AFCt$H5SHO1z z78`N}yqD5rAJa}=QZ3^?z+ywLh<}JnBsSy<%%h;NH{=RbA5daLu7LORL}Ej(z&r_x z;Wp&vpsx6a+$g@6R{IK_s~KgztbHB8f725b72Z*+7ZATFYey}qc9hrvd;hNxp`UF3 zs|FdlPC53!QmLp1;FYUm|Es|2hGYM$K%oaj?tc|%k3ffav|bU`w}}0(f*fi$X#cCg zrx}Cyzmmw9vSu}MMQq!1SD0l_)48Q+1jSMi6((`pJkz)U=$KLMxUH3Dn zLXUI*>q-!6I*~_{!*#8dMI7@C-Q_wniVTlu*!{0}aYmHhX_zARzrKq|VP`Ikx*B0> zjv@PBD|m$N%-&|AR!98^(V8xP)A7t6r+852DG0@T@dM#LW>bZs8>t}jeC(zQ!!U?l z`0a?-c1XIT6S1l-0pq)LNK#NZBq>A=Nq&bzlJ4Y?@fN=O06Q#FCsQ#FMno~j8UpQ=SrI3y`-IV34;J0uARJ0uBmI3x*_4oM2y z4oLx64#{wo(;;cmgmJ&%O&R%igs8Yfk_V(ilET9{Bnj<&J0i%WLy`b{O2{d#r)mP6 zPt^oFo~j+7{Zvgj=Tr5dDIs1~VCvS?=x@M62Ik700WH<^^YELf%)@Uyt@mO{iodb7 zQ!d@cl4fgi#FW0_BMPTu%`Xzt!yV0e9!KB%FR)7%tG|gwJ#9!=`UtC3r?fTWO*%ip z5H8QhNs3f#g5|5H_YotdG8N0Iak5@RdnZ%&lT^x5NJ@rb#1Ck4_z?Nw6eZ087}|XD zaneyZD*I1NyH4qGm#?ootp~W!xjS^F(X8}ydfe6IdKrBbYDL$5_%#$4Es&gwi|^Zm zBL&M3_?lW5t;WP`-qVhGH%DUmfmtj#5u?i>=rC0fm4~bQh;8!^bBjY0)d^!x{jeLitK~gKnI>I!fCL0P=Ie^ z44;^0;5S+!d8Z*1LqAA#3v%;dEuHXW2Wy);=#&tCiaXQl6*6Z%xE_XWeF!OHAv0Vn zywuxSEEidc<05a@V{7vf#|7GM#@0@?0dH)uqZ!WXcoCNthXtWZ0%fgkuVnFd_Jhu` z)f$vu%Yr_&rVG2Q;#FEK#u3xeUfTCzRF^KC3MO39H3TzDQd@hWnW|w0aQ`tfo{Zkry z;D(~D8K-af;V0|i^t^{+AkXJC12}C1&!DNKrqDshR9_6QrD;KoRa$5VD~zQU*nFxj zAP&XP=7-{+zGk2U443!{nb!lMaJqAAXPtj-t-qO{b(BU+@ijO<>D0auoRC(`0pNA3 z(JZ7o_C}x$SepPHu6Kp<22l+-?wR84HzYvGkOwNt;5bL0O;0XXR18qZ0)_ky7YBKXrFvWI6(aA zPT$zcDSn4v6LsP|4o!C+ho+zOI5aivtT75m3bnfI;!=MNGpTw=>QnZlKL@k6Uz zm&zEdfVX3;gTP&1io2Qw$uOhI$T`MJ-H`-2FD^bbOHFWH^ zYn6o4m~m3kU3GD@!8nGh`AkgQJfu2q7OT6iPN0>?ah0n#bkG^|cCmUBNWM6Envalf zJIC1@2CA{Wo6f|N$5~~$wk2EzyBWQh#y;1#5=MbB)ytx$jymSLCV?`h0uMSN$aO7e zi$fIUihpZ|foq41K;gv_mYOy@?m8Kl?1-~JXMuAYu9xv?;dt5~+RBes}b(3VA$qadX)S!BD-JI}URFg}mir4Lv72<6N zju~Bs@yLsbj+|RlP&jZXL=GH&hXaT1`az1cd{K!j=Pv!nOm4fUpCHAcq5oKIQ;?H(sEX^G*vwR^l^oX%7}w{~YPgG@=La_&TU zUlMEU>-hqT^MsXUi8NcFjmonGLT9S{=#F2E`*^7b>+Q$K2U`4VF?pT+Ph#g$O0OVx z9UEG(rDHI!d6HKmJvLxl&3plyAIlqa;j#tb3Em6;M7;Ugf5@@iV$TsETV%19-{fJ+ z;*ZZ@EfQ6H7d(>-Fgf)o-36I@8=(8@Z(zyZTPr|@-IdC7Vslb&p|*ma*pT-Vl&3So~0mtkwN*_ zAD{{>t-dXyikXsuQxj%kb~ci~&n1|WkL2wo!~D5SMvS67{7pC&Pnn?Tpd5v!5-zRtlsU+C^eCJLuuPfHgV-v{SJhmqP`%*KrBj=@bZT{% zPO6mdhibIr_+mf2L$uASN})MjEv`vWk*mRH48E%YJO%M!amHAv8id{cYw%O5!R9(d z_znO{ZK(~e!PJ$z8+ncL)BKcs73CGs$lAR33CJ>T6;tk`*~U0D$^FzM<8Xw;1Jn`N z_-a&rI|SG}1}8Bv;9_|9w z<9zOFXq9-*I9MyATXJaZMVF$Wgc^tS6RdB2ilCsDKk`4v!1T#taZ{n3pRHzS~KUx5@cWHNU_z8sdDjeh06*ja3l=6^gLp=9rYa2lB(&v8a}boZ|LK>(n-$7{hZp~NK6vANhl9Y zk4g3Gw&(lKqic;!@0FOoMw5$(&fzpBc+Vl>G2O>uF?4jTF;QYv!T_EmVVz()6V}L* z7#F7yN7ovYCDH^Et|;vP!&iWeGbJ{fu-4JF##s{U0TxHs8dD@3M=-L?marEvKf2b) zk(fkaupYt4m2fhrU`C#VQvu7PYmIz~O9PG{U29C0m{GvMKr&+*uMNB!ClY>itubBF zWJ(mBLSxL3$cZB1RA!v*y@5X#WdS3Pt~Ji_{*l+^Eas+4B?8_Qnt;D&!NVP0YZQ2? z>8#D*jy6LK-}S0fytV0@=1$fFT(WVk_YRnzXzS=&V}}$M&vg8`$#Hb8ah;4)V`xi{ zalN;g%dCf=x10yo8aK#zGt5dJSZjP+Mp@5)gU(bmZj?EBW7;XFnS6mTuh%VFkZ9-l-RQH zNnv73{_iA#DG8Q14-*q4FG&(lc=J8JCKuempRk$nvW)g}Cr3qt$oTgXn=G+{)gL4_ zExHUwAi$j-#(zmtqpZ;^QD-M3`;#O)Q*h(L**spAky8YZ$jCp-$Q+Rpr;2y*Q^oDnuStSDk$Nb> zUnIfQXdIw4ZK_Ntjx00!Wih8)?MKzdjH41=AkpHuHCUC`WyCCa8E}$YHO}5Pj!9f$ zw4FIKj>}w2qDz{ai}4)gJk{BFL&naP{NY-vTT>;D*<{9>lHq)3ES;!@HRZ-%Wn_6+ zH0z8oW}J|bm5xX&;ooFjO*DO)_+kKZcAM1qla1 zWc7K+QLXPA#R=`0ccJjsX|YC0f-r)NE4VyJ&nQhGtBPmh=)sn4ZUU8rpB5`l8V~a) z0p}&eBLk}hgX8ENa+l621}A1l6_;&jQY+j6aFH&$vOx5AW_XzMUXuFT=b0j2mV2csT+|W|?-|45|?0=7dtzhfAj# zMpf4&e+^(9AHJ3(Q%Pbgf=$@=QQJJXDcBLJS>4&X25-}OlwHeZiz+K{a70OIb#YZ0 zR*Y3)gJyN|d*Bqm5I?A3G4w9u$w_L zrerJBje5c6H@JGCJkKHLF}xtzR1k761lM9QQ}%B-q>tt0$fa^T3-Yl=RIEJW@)rVc zA~65^$Se`4Avw<3!1Y2Y=J_5$p3UQMvL8sx@W6FOyNo3OIj3+rN=Xh;eRC;Wk>xzf z(m>fnmh&mg41myx3Z(YY2`VVBe7QUi--s2Ds?b>Lm4mX1OVJJqZpXCHp#mz{jpp68_En$vZ!*%lwsv94OMBQ9Tbu$eh<%gQ6EOqGb zE`?ZBBBQV1sshzb$V_m*jiM+~S;ykGR`SP@_o%E@e&m;Pp<_&`2W&#>r*T~l4sl*; z%Npqby_>k$t$7bY$*4;!`bSiwqD}Xb+^n^LykJaulZw@dbmLK!zfw`QQl@Y;QRhmer!hr|0N4)@t#a)> zCGQCx6V%Y2pLhEFCq5K81J{F)SXIEBuWZC>ImL>h7v^3RL}kyRn5QIeV_hBXoH>2c z(#QCo#+3lQvAjJeaqnp1_uJ~d;{1(a-*4k1b@uyhb@2P`&u#Ub7EKF*XerYdtLGeV z_^3jxH+&S1c*94CFILZ?68@d5=V*g6f32s)jKnjGTOW&G6XpWPa<%yzo7+~^Hv8$E zHQ4)Ph5G9yxc0!hECXRQ-g=}`0IPWO3MqLMfXKvjDl8KFl$A($7p`9;@$DdsX+@Vt z%y@c9F%}je2Ie+{fT;k)$~2nPDl?S5NJe%7wkwu$cmh`(i{C@`*z*VgMTw_#ZsK3CU*F7A|?%wr_U_XH%KQ_-`|U_Bw^|ny$#V!K|BeBBZQX#AK(-* zy6f*WGR=s}M{+zrh6$}XBR;@63GI!wBg5|Z6Kqbt-;a*=7a+Lz3D~*c zPhd{A-;che8nNH+BlK~5zu!>+pY63ul)XkoKbs!eBDVbzTYK9dX}GoR?`cHv4{3^R zfM+Q$5P~m4v%ZXZ9Bmn6sxy_Vp}t0W+d7=|kCn;iDpXDt9{_xlH2*whI@fNUXlE;A z&BC7AC=-g`(N@T4Wr!f;*~wHaX*7Iw%6 z#v&e}JF~Z$U<2cBo`Jn2%GBZ%T9anfuY;mm0RJ?L%sG~!$&Ze%SZePZ;kSjkLI~r=6n(2dJN~5w1tZ6u|!*E;$_9M7I zy;x@7cp*>DQmsszR*{Q$`)U?Xxf8&ZOJQl0ICWmN-yRp`_f?e%)V_wcvbvDRM>d`^ zk<`f0Hevn}ky@^i#1ty)05}`kvvUgBNYaK;KZC+5Qz(B$8TA_ivIQ{O5rYF_F=-p^ zh{jp4G>y9lHLtRdP;aL+6~bY$Ep?}J9+Zblr)zE^#%rW^`VR#S$r=lLz?d`an?CG(h1 zzcDom*2TqFPwO|O(h1wdzZfTg;NgUhA+Ny;G&t7ku{lM*SrVuqz=xS&pe%Q-{+-mH z@X;C{X$`j3;S)UNIBukaf5uq9CG|Mxi%(S3>s8^7)Nf6l%(3|PDt+C(l~(J>sGTw@ z86~IHg!(RtNE==OusL67f<1F5u55jOKtmV ztRG|g{W8J}N%4u8wobee)*ndi;?#8H1~rOV`7tf0?@6U|zuh`UTV@VN$n*z!+v5UlZ7XT@y-r8O)`1z^cUKDRk^Mprb*<6rX5I7A+1Q zA9o{S=q*fZU_FgkJ2_~w7=&@yH9$ z)%C>A8;{kBofw6hFCcC#;rl?6k+}ue)i8IXVA~U)268kkPSQ$XH{(it5t!M)h;h@u z?(FH|;$n5Bohwr&i<4=QC}$EL?vZ9QSf=puPUhvsdjL`1$-KPVb^6X3abU_>MEe8E z$E{Q0XpoM~EXYsHcjQ;d^UFhCkK=k4Y2UN+E0p=A!fUx!V7VSWs=fJsLI5JuqSmkus5rZ)h(g9^YSrgzO4b;wcS#&W%sm zv@z-Qxh~pK33R=HTF36EswIo*e3}86D=wx{F@y^-4;Pha`JgR;|gW-^t3QQ6{o7vZrC)8F!P zyw}BW+Dvi}T|MMJCctIBarXUui(7=c}w)nK5qA7={qPL;T>Z8!N6paVnJV;SG9nqp_ z6g0^4Kp!cLH<{NWjhn*e41}mQevAuV$fp5D`SFAIYEfV2cRh+0wZmRSZ^B)v#4zx2 zQpKG-vM_%t);1&8K3V<9(8DEgA*Of%1oInOAAJ;kffm>3Ee zNs4C1#1LKq=!&(83ZkK~0OLd&0!>NOA$Q_1LbuAp zW7D$0FdeUxN2V}hfH9T=7z!tHzUfIqCQdvCY2&zv96ST%qQdiXjm-gHDlu{K@pvEh z(AgC_E=Re*Gnit$;h@Nv!E?+EGZJhj#GsQ+3}dP33ZtoLlfubW6fG-9aEqDb;WTL8 z$ub#GWk~`_3C|p((keKI$b4-Vr1psAzU*I7nm^lM| z=-e=oz@9e_*jbVm$}F(6or$To&UdCG1da+A+C2snY2p5ITIj>Aop+UvxLSi$;fg4k>($&}UD$gTzMGx6raU=#s6>@!?{l^9`><3E>1(dx<$x9SU8f z4Ct0cU9Rhkz-U? z#0xwm!YAb|tgRj?f?Ar9r1cGwhp8#PQRxQ4+` z?o^4Guz+N&JOCqXMQm9Aq3UGlNy%-JPgC8I^&D>M$Wg)N92MMQsYH{S!pKKi>Jd#Q z?9;R}Nvzu=8#k*)WJjl=naYDsLH*t>w8M-Xi=&*C9&L@qG1ge@kiVf|4Fo}CW%H<81ZneQ!{*$#^$ggxtz?NIjcaU>eNiG z>)}eaMnSHWVM8JHdm^Oygb~mxOL)rZoN2~|yAg~+q+)w5#ZHK9$Hd5XOmfZ=lR@g3 zC8nT&_Q0AN9!tfrJ0jeOQ10*~PsEOtvApD?WD9X%G))TA!`#AiI~-eNsTlR3Gty8$ zG}=kEBb-lY+PE+l>klKxZ=B*JrfivxVHJZww2vm9wxRws+9y?tR}}B_C!I-InqgW7;1e_{(!_e4 zY82~KBho2pi=k82(~CD!i4r1}2s0>Wrx6-}d6ZRl(G6uY!p9h{6_`!C^>{CbR*Bgc zpI1@Ej}#NEQB>j7I%47vEh2zxk~8mc`;j)uy64&ysa%d(6b-tTUO9+>9WUFQ=57Ep z93TYC6bdyVTpBT78`i=&%?g(h42C5P8;{6ob!6`jPnDcTh!31(f`*%cgli@`vK)iw zAH#_nYpGitsddEsk+}8&kw67;WiZ0 zvs0MWis46hYR)J4O04#?MtyFd!Ul&|llAZ>CkQb#86d;x5mSL!QRuj^;TL8i@_~)U zh6LLp@Y!;rWv7#@E+5ebPUk>MWIa1u0gW=kVY0czX`%z4#K43rn9Rp%X@fA!Q*JY- z+F4#29A{{04u**^bNITf26KyAH|;9rMiyuE2_p+jAObOA{?17+3XbNpGNF2ijWok? zR-2%P{+)k2xyQc^+My`_L@&lsDF`!yb8>R+|NM1DHs0f9V}(U7E|yD2$kmJAdht4g z$4|}4%gN8J53FjcZOz5Wl)0T9!Q7^^3(n@ToX@nWxp-sH+=(s5b_NJU=3!BsmV9#C zJL=cq1y>zokX;;nj3TaUYHbbWti~%3Cf-kqFwpgZ1`(!%VekoGJAz;VbcE`$XG4VX z5+o4B<~l%l>l>=Wj#v>vwZtwkJj(H>|!mdS8IM!dsTU>@s`G^=E|qEn=UsO z{9JoMY1pN`ak)7w^USF=QwuWBES&zfdQNhou4;etJc;q`mW~FT|8V{VS7OP9qOE^e zi#DIrI+tlNIXj-&^)kqQ7P|lu`-7qF<~_@`I~8+**|ku6`SRY2uhSmgxJ=v6a`KQ? zb>+CUm@7D!&RJWv=qDGRcje~gOLuM6jPQ9Q@d&7 zGXFvIg-sVXp)5b%_-gf~*J#lXo5|*EZPlwDMlsrN!TE z1yutISqgnr*#)GPr>3IJk2l5gQ+}k>pPkVB~0ZEnG$lep?T5a1#GgMJqp`|U`zUvw-u2;M0;hk@1 zFJEnTUNrlu`tzq;4DFevrQND^Jgl{tZ|&Umh?ah<7Fec@zExWvTK-t$nLp81KD<-Q zGIO*MimIX2UO`Q%?3bTYeT6&!CtDjvT~~Y(8*S|9vM>>mot)~9KB%jCl_ab(RFt3c zLhk{HoI1~aC z4C`|b!a_S{8J}`yK?gk0T!Q8$;aLM_7QE-;yAxWUqAb&57iih0?^1L24U4pt=d^n^ zUZMS(nF|h#+r$0K?=e)A1X!o zv*GOccwHfC9)mTdN#BW7QeJGW4~>~3w##w*OsZ<^zuQpb${`w6Em&uDqbkOzr$ieO0bGu}WK?GwZ^q-@T+Gc=2oXi_P_a z%l%2w^Vy3Qb}ZliUeP1j6^|VAYa2orF3(;>Bu}p{$5Tta7PBDNY`)-;N6pGf+J>At z|G1Ip%V(dryjzR%Y3p)UVtQP4-47SNy%;m-#Mwwg4^pm>Yu&=@&9S+AVZ?j2HOmM& z_0I>N#~+V>j{j;Mw`z$C9?4$5T^)s%Sc*3IY|liFJ^!-*`!Z20QA+YuRRQN5-o|fy zUTu6@G{rF*htCWcq%#i7D+ks*s)uCdf~RsfUQk!DV=>kHkMX0H(@*fqNASo@L4}@z zXdA^4ggut$h0l@`ZquQ25@JSv-ckE~v}1tu4! z;ce}{jdx$LWbv7cH17f}h^bk2ZvLXLL5CKFpx zhEyaD@q3wo8yw>336O=8x;zO0j$p8;zaw_;r+NOaAI7qYl)4+;tUR**>@Ddh*BMhEe6O+F?3kjTp`_=-4l^qCvN7gXk++RmJD8sD$DUXB(obT$t71!j zsAe;~@J5==0!du_DH6K=y@{H5{1A-EAM;hh^GQr~JiL7^r#Np#uC=z|=2}cwQ-bz- zfae{5Yi+9f;Nsf&`X$vL0cgQ1UEWGfGjT2!21ZBQQkytf-S(D6oAxidHGW$xw!eDu zqb)nTvFTH9Q`4i%&R#B=ARTI3BK_g4C_rrQR(O7&;i zhZwA!g#%QgA-`uq!A&7Hg?Z-WqSIt=qq-y|$MP%}Xp6*nTO`8Qu}xH}8|z;}#W_X22>Fyg z=h|#7$b;vttkeG3uWCPF)h)^t7&-x z?t7e}p={22a8b%z=OyB>h{`Xmk#N+C7Ig9dKJ=MGpG>($r-b)*aBW{wy+MIWy3mG?oP+vcGH@>P=A56K;5YL(Qkey0YR2`7^e-PC z_6$?YE@6U|&S5hKZVV1&-#B*B&B-YSYX&Jf6TQv!bN$7sb2g*Ef*ZFW2oz)zG2J` zkLejF)ym=5TU5P&qyRC(Lai}fVU27b3-FZ&$FP(;*ZdpJ`3rT-JNfzk z2tK?WEcIeLtzl0u5VWN~vbeQK!%CmQ62_smSuN~Xq3dM~gMBQpZD2llfb2mpEZMBK zw!!C$+N@=(aBJN&SVEbrb{k&C$irO&BfDFN`gCb!KeHHfIc+WvLT)_e&HC+NsF+@U zS-H<%aNPH^W!8jMOU4E6Lg9h)J>{9;)Wm}09AQ^s{pp}~SeLda+-6w0+g=siEIA)t zA-a62jBU;$+a?USn~XAp3QALJg_%LR_FKR5T6EQFEPZBvaF*&@EUg$Sj*ghnmi0}; zMb0&Q6$V)2+{>x87z<PW!mV#M-RI*0ae&^rse40qyp0>D420h= zn?ks{RefM>XcS}Bdc3~fTeIon$gl{bb)uHim6H|}T#=?UQ{)(_P9rIIl4g#LS;2X( zPk?8m@XOj?gmDpzGN^S7@@91gu294EXwbm0br47+4L85JTQB(ATDDkvUip@Nq*u00 z-JoIY``mj=K3hhO{5I>XXcnc>>%T;nsSykosu{}XvT8+quHm3oU@A9R`yNzm7>mR6 z^HnT{4|idCR4j?FwihfLGu}A;uVVqup*Sz9_DXTWt&(pb?9zAum3r_$gM+k$rzM{v zJfrc1=_*B&BJ7oXoKSYEEu}!B5^)6_RqAfcLdCp~s3ofvaso8B;GkT>gOX1WF2&rs z+8a#}rc}NZC;Ys|izLq@kI$%b4Mzz75l5BR`ES+uHW9ZI$P%>Sz-xKWcQu=GsvxPV zy@n%%Z&lP+6P&B4i{2#{9buM*p~^cU`7=s-!x6*f2atwGEQ$$X5{w}7e*mnOEKB_& z4q#28{}U9-s})E-q$s;cd9k9Te^eqRud!0s*^wqJ`@#v=w`!s73){U@R@(IF^OFl(-SmO!rl6;)-od^NSBz(8z6NDE?K2CVE zq?`07lh-kS0NG5`@1a`3AyIYdqnUqv?zo6LVC!XkuqgRBp$@PHkOzqkh4m%83P;Q< zO{>fXeE~qF9{kVXATc2y`zT^&bj<@N{~B-);iyuhAu^Is2UVVsw5pPTS4%zxpi&S1 zr*TjgVV~p^gjvbg5cW$xNw`b$b%d8e0P1#1Wg2k;Msd);?IyqniB~RD8j7-!U+2dBCk>p{(l4qhC2cZuJW!4 z8C?UUN^BVvHK)YSgXp9X5^zfa^!?;GDA_!~lw@&TB{FCAI3nBwcrT7BOrt?X>gdSD zlE0^Lr8wcel1~u+naYnQ2&V-fCv1gbJ+WH$+9xvkt{3oR#ll`Vu7IW&Qn)|8N_m&zD-dDsFhka!h%w-$AJ!c z&k<&*LL^)w+Fi#gYwfNhN39*Vq*RGTZ^l9I><7F9N5oKU-k0ED3==j=9v|U)-iYLD z2=f|G$PgqwfJ*-p|GRNS+V47zs`UzWcU3npZ~n!Ccfo~Ak1&LEkBpp3rZg+aW-6Dr z>Z{%aGPmHMK*D{JSKZ-$$=47bkbIKxW0J2U{ITR42!EpSg#Rh|B;hNPuOWO@@(Ds{ zB#HvYB;P=okbE8Cn{{8wrM;{snm({E{!7`lYD}3x5gXV37ki70QPBGLVYt( zL-?HFlZ4-ud=23#$tMW^Uh;wNg(QxEMa5-pQXMp+< z4h9HetqS&1g793)2f|Z0e~-oyzE|=I!VgM5Nw`Mi37aJ!C(KAbNw`b$3BsJ@13ABf z^BZwQx~@D`!niSFhz&GLFRP=Wt3s z5mS5?rz{kqVi#G3gH9ym41=wQFe&*IA@BQ$Cw!aaa!#kDO}(MX(76#)X@YFhh0`Qk+>e=MP_)kepDzfU&{Qyo6sj7XVdazszYf#>h@W zcJT@CaQ8WfJI}f32+vA5-sBzLc+RMI(Gi}onu|3e4;;_;MsT}<#uhI$pm;SR9C;TQ3#th-MD(1sE22dy} zh7l;Vh)!e48pZ&d1$ZP0-z51uLfQ@Z2Esv&C%jSeNkTo>tRWN|mlA|SLPM4+osa*# z$-x5=uJ*_*Sw;N22B*KQP@M$SIMRmlI4$C!lL_yXyxN+J#v`6kkBBM4|Im2C*Cd|; zQ0W2u=M5Ly5W$aB_F6+3Y0tD^l`T@;C%i-QDO5rwzBc(Gg~KBlz%4j1{~&2jvbO?Asqle{DWy%!g6kD^C&31l-AW+r zI?1l6u$_ioWRf$5EBE4{VF|x1`4r)_#uF|e9mXmRp_m{aPWy6*LyZ;CVU<=pTuzo4nE~G zi5 zy#;M;3l4K@Wy+QFoD0vX!vqe_DmZU2iS3+rxm367x$x%t8}R=x3)J^xXKbj<(fzfb zV&B24-~)Nf5S%zLRe33O>nUgU|BvG|X=v1?PvJiwV6$PwJiHMw#z{dnA# zn2bKtr9e~2mekuog283)J{&zbRDA&PL>NaMj*#XNoK2t&gf!m(hDmegODJH?I)|mc zjWa&vXDKuuq<_W1NBM%O$NB*!g(n7jRq;{&bs8g}z7KD%XbgG8NLZHYdyAYEsidS= zrQ{^?zrGMMV&jfgy*qL>%<^8GJn-TZXqa;a@);^MosH&PUF^+@PYs08s&?Y`1x$-^ zpgxg4N1@ff_iLJ3Me{MxEDA5`9G_e=(f6^c6#k2~kqJ_}rgaM)NuBR#C#+O5>$0ZGkub@n#g}6^>qlp)Aff*lNSH z(0a9jwdi$OC`9Ls7PPKt5m_?A(CGI55E>4hSFtUJ%~b3|!m?!AdkT2*1^>H=ZICTb z+TcSVaN7>sAX}ca!3LKJFl-lW4bm<;92%oL9Hn(PFC9r7vw-RA7E1T!;5nD>(}C_^ z0(E8Gx4aJB`4D<8-G2)b#P7k98o-2!v&(7a_f$o{lkzxdl4zRYc){m|t8qnXiWheL zJ$-&!y(O;tUX8iQqu&HWJ};uwBsxR82N3Cux^Lq8G7<*qY+A|+loHF^t&Pk~53mP$ zX(`RfL0lx&3pT(-o{J>yQACa|#bq-~P*O}8a zEwsptG?2A?$BrGO5m~lQiVta8T3T3(8EI5~+FDl5CQE2`1U^;vp#(dzb?;7@*1ZKH zFSiMB#@2mv5aEC7RvI)MVL7hK2zy0E8ji3KHRlM+aaBgxPUPIgo@5ndNo#7r8UD%= zM_7)lGQu7%yDFy~VW*Lm5%vIb^jw%skMsagdV~#DV+pD7lL+`s>6TKlH`YD2&@jg6 zS-Z||+hOallj*TJ;!E49K%@NL(aKg8#-S~XTwCBgL|LLQ_>+wIVmYqbe2g!?f-B++dG9n_Rz?`| z8PZYhi)vSlB3cHTX+sl?DN>4BoF}Xz|BZKOZ`P}#m-YO)8P`cC^Il}i5-q<0O;^U# zNsv~y{1*bt?=IsYr?h+zvU6GfD)14@|2e2#lhE=5IK=XepkeL9WGv5n6|sC|i5*R5 z#^n>rsx#O}&q-d74cow%bhFv;JLuZPhJ5-8CCd_{cLkcjTyqlc9WvLrd>Xt(_sH@( z5qTd#P>Aj+uTs?cn17ypVtG;T2$&K zSc1Md(PVtVyLDRJPV_|z!-V*Pza6=WHvA*dNc8@-O8^XQcxPZk&MNF=?2`nY*vDQk z$WZ?hTqyRb9O14F_k*KtBNNZ`)m*)3XhYkdrarXcv0pMaTm&f}b731)1e6bNc=!Hu0Ec4#h9kdOaGiY3YX_^*Xo`a@i2P1TL zJ{>Kz%}g|u!PxkVb`u-7;f%Gj6Jz7AfR^^<+ZXj2+t*SM%r!c2-XgxxYb}*=y9O>4 zUsP^8B zG#&VK8%nt1*iKId?Udek6WeJItj}1CsnxG+-Ay~)4mydAaGk3tx6jbEV4`LPZdC%G z3Jqn^*LFG^pYo1srnXG3^w(E68Gr4=nXMOT=&ud1q4)~}S%pMjoC1C>Upx%+(!#N- z?f8#EWr=p?cl2WC<+w_Ng~`}?9CTvm=z1aHlcO)7SW?@$Qa?tHUja?t&?phl0>gSK ziz&?afa$g{F9LHEQ&f?eL~gOZ32Bp zFSl(mUT#C}S2=X_@-2av*F#G;u~lA#5ms6y-}`hEBY}>cEfV-#{bi8JUH_9V6JXdI z(}of){|)saV>_|seizn-La=kMeNmq=qUcvzFIIIA{@W35BI*d}bVOkf)C@NTwbJ>} zwg;WrOf8qh^`MzFG^#Y;k3D5!x`D}`8;zd=Fh?!S$63n4908{DZP8Lkftj!{UkB!d zh50vNdVV2Vss`4&4mFbqH!}y(i}vAfxEHFLn}25$s{!XqvjRPWJOW=p2xPt8h_E1I z^$-|gfB?-Eu)?+0b)GO*pMpcBM|vJ-ZepxXfto}Nv@mH1@t1YO-T(Qd4B_vkwLkat7sfpExa7AJjkAM9B{3Q)`w7v)KO`+&a zv5F$x=(iNm1ihAEXnFd`PG=JdJt(ST%r%5!N-rNDGG6{XaCWOC5xx9Ju&Q{u^8A?| zY{oI02icQ+3GNf`>;PvV$`X4CuB{=KUyiE?(?~LwKLI+ie7Le(gv@(Clx~>K^7;Bz zt3KGYigGAHtb7GZ^_Wt8KCgbcIvQXo;cC(V0-%&>xgv}HV$ViPg~|07%i6k|d)OXa zQJgEZTymtpMu&~Ruw9mi%9SPh>#qZUeXZ=OoU&Ek3txZ?bv{;+hCc1VF_%xzMZYRO zy%f~=D@$x~_XaI)S=m)NrQf;ciTJ$-NIMRV-+u@??f2+%cLC2EV7wE?Uv5){aR3Ib?e%}eCSJAUZyF~ zIM58C*UWzZMBw+UK#jk$#CE~;m84xfjjNOzCKDSgQB7$VymmiIgvt0KkFJ6eD%x59 z67hO`amqwXm1`SHr7wQ@fbj*T+2aLi=!<>OeXe%#EN14?F1E6mm5lEEoL+R7-@mwu zceYSaJ%iExp0m<@=04&1KzFMu!3lM5K4^6RI`Eb&6diSc@O9{ZF`OZ~ZwdIDjM4pK z)JJrWuC{5Yu+A35Pbu9~6@P^x<==p2+Ry~ECMm^exh!O-bEf5@(3~yz^;oR-R%5Y` z!j~{jS)#@MA+XqV*;P4ZtDMF$TdQPGJ04gyi-JIuC5~47{Y&ma@S;nF#8$}_%%oK| zg2Ij%6LqId)On7@f>9>0k5@m)M!5X)=iv|hd6qt+{OM1fbJD*+Hx}SEWf6bA;VqVf$I?`Wq zq}P;VnwEtY(=p#LFX>4~I_Iml?q?j`pL29yJum4sj`Wj`^cNiI&p6VX=OsPmNI&gJ z=hVQmM$>DK^!4+SzSNO^s$5p%%Z~0paHMz6OZux}{OI21F-Q7yj`Rl>Ncu~T^hX@& zCmrc`FOYQJNm)K!^{^xTgd?5rqv=w*#ciLL<)e>%OeKK22?*#kAiK z%}Y8TJXo?;Jy|ZR@sy+c!;bEg^OC;WkfJiI-7g^NS(Fr zYiH5jJYo1b>eZMsRxSHohUytD5+=fDrn$V?#6}gLZrRB^*Ww!h@?2|Xzpp`2+waRw z4TGmxKS%pqN=@eSdst^;cNZ!K`2n>V1AtXJ}D{ z%9r&Lq~Y_JlR>XV%frNxWFoMr9!gK2yK ze3ZWors@2!f7Vu=pY*#O={ZOG0Y~~Fv%j`RUX`h+9>#s!j|cciyD(yw!* z|FP*;gPsi}DxIC*OOEvQj`SYz)pnKDM{ZOOAB@ zR3bdNcRAAeuHHiEe!C;R z$C19rk>0#O()T#hH#*Y$9O=(2kl%Y8>5Y!`jgIsi7D#%ZBYm|az0;A-3bdNoeLCo_c_w{IMOE_=?^ZD^y?hy4UY8nj`XV* z$ny6%(({h=Lyq*x1=79Sk-ox_-t0(UzCgN9Inqmx^xGZj_brg_1CI1Hj`VIv`mZmL z?gt#{+a2k7NBYtQ(!JA>9=WrVc~qlw_t#XjK)O#j(z_kqbB^w>2GV^$qrS#X=sPJ~ zKw5=+5T>90RPHFS^dT_MUD+JL>~v`MX$*M?pTiE#6#3}8n`*V%#-N{8?^BQznEpaG zi<~@tN@+fy$3-)95YA5mGo>{Z%(sA%=d`BO_sJ3|)M637&#*B~z&v8{X$QtcuW^g~b|;z?lA7FwMZ+ zW!0w}7~9JQVE6=v4OmKj6d3Mu5?b}QfLX4u3(dX2$opEXkFE=%b%!F(SW^VCQ%aWv#*7H58W#vUN# zQx6ROwB`8)4R!IE!@b%a_j%qkUO4Ujxn30HZe29Lad{D~!?NuRvpFmGqbF5ZD%Q zM#g&)G)!T;sMZfYL(F-=oC@kp>I)p24+3+@qS*+{84I(6rC^wl^AIpS7R`QOrY+1J zz_14h`?1dfV`fca=cj;q!7BAFT`Kg>KLSIGhSFaFrWpjn*_UlPz0Sa@Aok9~OV(zN zBr%`yZ&L4XhMX@14P#7N6Sp1gV{e1-4ciyLDx0)wcm*)c7G^sz+XLx-ad78wI_C`p z7}h5Xnumi@_`WEIQO1+^*^J){poz>|`ZKwaV%A%2@tGh^z=xba2@F$cpL-q5mw`EH zm3j)8qZa1dPN_2rlZpxT0s0NtC&y0QvQHgo?zT!@49p9bPuqcEOEIyCFQR~19hCCb9TB{2 zaUKT^Q&{Iiz=Zu6uYCp>dO3`iV@|1OfVnP|B}1jR!jg3wH1_ObF}{a*2%Mn^xcgnX zY&PG_;WSd83qiv>%}}oTfjJ#uj^M1m zFWWo1(@$fA(w*6&IUOACA2IoKZ*L(xX3lcl%2*fbFYp(AeFDFlEc;=N)ojt0%qF{I z>D*u+c1%UlQns)j`=aKu1<%LVyM6{6L31e>1_`!{R+W$o8a-yMLcvIQcGHSD=ON(Cku%iVzF~%&~hnkgH%(h?DN)f|| z!BF+9S|hv9`uOhFFJRB>A`F6g5RD2NVzJ+{gE!lT_d(I-OD-j;LD6^`rN6Dw8xRj* z+OJHO13wnTta{wfWk!a_v}qwKgT1c({0QcNbO^?78zCHn{e^c9kD|q8viZ{B2=*Np zKO(kK9ic3w2a8z@%j)YMy7Zc2wy+7O?FF*eRQO~Y8zmP4vampF*S7A~_4Sv57DQ@U zYm_Qv^BALid@w{Md|%zG@D^dDFkYWWAk;T-mE1jgt6%K14*6h^;g0M1?BHdqoBYD) za0y!rgBKzd%b|hMZiEi4SHG(1@}^5bdM(2gYo3Lh3H$!q!QsBncFh?y*7=p=o3-Oa z{dL)rrd&Hx(0iG)!sS<6M^Kw`X6<{j8Q{R9vprgaj^gH#VXB<&&1E}=TSp6p>~Kj@ zguJuEqeI+RnRdzz_7>8Gacsjrgw`F1-L&dRhp)A-edI~c%TtZ*!uj*N{Z$xin z?=yfDvk=8r2NX>>2+Q5XEwLl}CKHcclSg(9vcKSGGm(q4_`NxH8uAmLTzYbk4*Sy_pK+U(mc??9c#VvZhh0LRhO;ue7&i5 zXJMp-HAR{)X`-ex?+FeGSC3{3~) z-kBRgjg~ox-aehPI>px?O+b(gOK{&+4Qb@bjf4> zR^8XO=F-Jtwg_b9u34l7J)t^9Q{9*@me9AMS4J1ql`YL8)R%qFwJOR!+A;V}Iy8rm zc3T=8L;od1oZOe`!ri$dgrc7s%_>`|YIFn*uob-o77x$qPKYFJ*&N2)3Kx9z6#1g+ z4z+X`QSp;I0(oqN;3}juuo@z8FjJ(zaA$T?)*tC-1v9(YREN;ec|mL>_u1uST&SY} ztw=YNzHy}B7e{-G;~4&i{IP7I$N`1deD+UxN~*M1nBna1A&gSNwZX_Wk(eGT?v$CJ zDL<(1LfM;IE|NOV5}b~Er0-^DmMaze&;am6qL5*AMEKxHFYuhdfaMWtu!gaX#eCRmEY8{dEGX@V{=z`%f^j16r*7Q9l8fIyHqE_>cjS!6#Bhs%r=6^ zQ}+UDj8W4Q3`skOhcHxCnL64%!PPG zoV%LZT79y3AJs0*eHcYtEB0lNKi$z;Xay2jHD-J zX`|J~Y2d=p2M__@s^SVV#A8WTFS4Q9l26))z(#eq?1fGVavF(hh5-jBQaQvCU zHjEj%Dh%lQxwGe2@>x4)IhBSi@sd2y)8VJ8CP5JTt$TnEmL+O};Y#(C(P2mewG`3Y zkIuWp@hRwG^mB~B*yz=^s>xiWZ<9ucnaB_(fpo0C4HNuG4oxSMFPWPsV^PlgaGwdz zx_=nUWO8Vfn5m_UBb?v3a}`q-dUvUTv>P`#Ek(?7vdpPr!tSP`1EttfJzO`YEbDe8 zN>%rP@tSqBJCxzBfsx(lQzEs7uBxvIYOVS{-P6ocPhp(L!vG22(3Pes2V)iqFcKF> zN6bLn0gT*$%p5cPsamT!*DOt1jtnr-nMn>qFz?lK>76nUQudj9!lxe_l{fRSFQol4 z1G|c)UAQ5`NpxZsZH4mlzZoFI@QhXxhQ#3MR$kTBJc`nW7z-Mq>DtPMk}`h}bPS`5 zz+B!;AG9m@B*K~#h2D!c#ENs*nWv|`e~%7J7{h1n2qT@WjM+1f$$CzOK^HZb0gbn+ r=GIHAP3^+LR2l;ZTk9r66$eH&0yR|PIfeQG#4k7R9KD+S0Q-Ld`s&^q literal 0 HcmV?d00001 diff --git a/GCE - Vectrex_MiST/tools/tools_prom_src/binaries/win32/make_vhdl_prom.exe b/GCE - Vectrex_MiST/tools/tools_prom_src/binaries/win32/make_vhdl_prom.exe new file mode 100644 index 0000000000000000000000000000000000000000..7dd3525d1be82e7c5a342be5560499d6fd15b784 GIT binary patch literal 100636 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 literal 0 HcmV?d00001 diff --git a/GCE - Vectrex_MiST/tools/tools_prom_src/binaries/win64/duplicate_byte.exe b/GCE - Vectrex_MiST/tools/tools_prom_src/binaries/win64/duplicate_byte.exe new file mode 100644 index 0000000000000000000000000000000000000000..425e90822b2f57da8560b09b172694a3f60cc33b GIT binary patch literal 117095 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 lpY(m?GR)K7P}>N1s;ft6^%!9m$`Dil~% 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 literal 0 HcmV?d00001 diff --git a/GCE - Vectrex_MiST/tools/tools_prom_src/binaries/win64/make_vhdl_prom.exe b/GCE - Vectrex_MiST/tools/tools_prom_src/binaries/win64/make_vhdl_prom.exe new file mode 100644 index 0000000000000000000000000000000000000000..1e5618bf9417eaeb90556e3021a78e9860a815e8 GIT binary patch literal 119861 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 H%=`ZUgl +#include +#include +#include +main (int argc, char **argv) +{ +unsigned char byte; +int data_len,nb_byte,first_byte; +char *end_file_name; +FILE *fid_in,*fid_out; + +if (argc != 3) +{ + printf("Syntax : %s file_in file_out\n",argv[0]); + exit(0); +} + +fid_in = fopen(argv[1],"rb"); +if (fid_in == NULL) +{ + printf("can't open %s\n",argv[1]); + exit(0); +} + +fid_out = fopen(argv[2],"wt"); +if (fid_out == NULL) +{ + printf("can't open %s\n",argv[2]); + fclose(fid_in); + exit(0); +} + +end_file_name = strstr(argv[2],".vhd"); +if (end_file_name!=NULL) *end_file_name='\0'; + +fseek(fid_in,0,SEEK_END); +data_len = ftell(fid_in); +fseek(fid_in,0,SEEK_SET); + +fprintf(fid_out,"library ieee;\n"); +fprintf(fid_out,"use ieee.std_logic_1164.all,ieee.numeric_std.all;\n\n"); +fprintf(fid_out,"entity %s is\n",argv[2]); +fprintf(fid_out,"port (\n"); +fprintf(fid_out,"\tclk : in std_logic;\n"); +fprintf(fid_out,"\taddr : in std_logic_vector(%d downto 0);\n",(int)ceil(log2((double)data_len))-1); +fprintf(fid_out,"\tdata : out std_logic_vector(7 downto 0)\n"); +fprintf(fid_out,");\n"); +fprintf(fid_out,"end entity;\n\n"); +fprintf(fid_out,"architecture prom of %s is\n",argv[2]); +fprintf(fid_out,"\ttype rom is array(0 to %d) of std_logic_vector(7 downto 0);\n",data_len-1); +fprintf(fid_out,"\tsignal rom_data: rom := ("); + +nb_byte = 0; +first_byte = 1; +while(fread(&byte,1,1,fid_in)==1) +{ + if (nb_byte==0) + { + if (first_byte==0) fprintf(fid_out,","); + fprintf(fid_out,"\n\t\t"); + } + else + { fprintf(fid_out,","); } + first_byte = 0; + + fprintf(fid_out,"X\"%02X\"",byte); + nb_byte++; + if (nb_byte==16) nb_byte=0; +} +fprintf(fid_out,");\n"); + +fprintf(fid_out,"begin\n"); +fprintf(fid_out,"process(clk)\n"); +fprintf(fid_out,"begin\n"); +fprintf(fid_out,"\tif rising_edge(clk) then\n"); +fprintf(fid_out,"\t\tdata <= rom_data(to_integer(unsigned(addr)));\n"); +fprintf(fid_out,"\tend if;\n"); +fprintf(fid_out,"end process;\n"); +fprintf(fid_out,"end architecture;\n"); + +fclose(fid_in); +fclose(fid_out); +} diff --git a/GCE - Vectrex_MiST/tools/vectrex_unzip/make_vectrex_proms.bat b/GCE - Vectrex_MiST/tools/vectrex_unzip/make_vectrex_proms.bat new file mode 100644 index 00000000..549c127c --- /dev/null +++ b/GCE - Vectrex_MiST/tools/vectrex_unzip/make_vectrex_proms.bat @@ -0,0 +1,14 @@ + +make_vhdl_prom exec_rom.bin vectrex_exec_prom.vhd +make_vhdl_prom scramble.bin vectrex_scramble_prom.vhd +make_vhdl_prom berzerk.bin vectrex_berzerk_prom.vhd +make_vhdl_prom frogger.bin vectrex_frogger_prom.vhd +make_vhdl_prom spacewar.bin vectrex_spacewar_prom.vhd +make_vhdl_prom polepos.bin vectrex_polepos_prom.vhd +make_vhdl_prom ripoff.bin vectrex_ripoff_prom.vhd +make_vhdl_prom spike.bin vectrex_spike_prom.vhd +make_vhdl_prom startrek.bin vectrex_startrek_prom.vhd +make_vhdl_prom vecmania1.bin vectrex_vecmania1_prom.vhd +make_vhdl_prom webwars.bin vectrex_webwars_prom.vhd +make_vhdl_prom wotr.bin vectrex_wotr_prom.vhd +make_vhdl_prom AGT.bin vectrex_AGT_prom.vhd \ No newline at end of file diff --git a/GCE - Vectrex_MiST/tools/vectrex_unzip/make_vhdl_prom.exe b/GCE - Vectrex_MiST/tools/vectrex_unzip/make_vhdl_prom.exe new file mode 100644 index 0000000000000000000000000000000000000000..1e5618bf9417eaeb90556e3021a78e9860a815e8 GIT binary patch literal 119861 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 H%=`ZUgl" + +# Assembler Assignments +# ===================== +set_global_assignment -name USE_CONFIGURATION_DEVICE OFF +set_global_assignment -name GENERATE_RBF_FILE ON + +# Power Estimation Assignments +# ============================ +set_global_assignment -name POWER_PRESET_COOLING_SOLUTION "23 MM HEAT SINK WITH 200 LFPM AIRFLOW" +set_global_assignment -name POWER_BOARD_THERMAL_MODEL "NONE (CONSERVATIVE)" + +# Advanced I/O Timing Assignments +# =============================== +set_global_assignment -name OUTPUT_IO_TIMING_NEAR_END_VMEAS "HALF VCCIO" -rise +set_global_assignment -name OUTPUT_IO_TIMING_NEAR_END_VMEAS "HALF VCCIO" -fall +set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" -rise +set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" -fall + +# start EDA_TOOL_SETTINGS(eda_simulation) +# --------------------------------------- + + # EDA Netlist Writer Assignments + # ============================== + set_global_assignment -name EDA_TIME_SCALE "1 ps" -section_id eda_simulation +set_global_assignment -name EDA_OUTPUT_DATA_FORMAT NONE -section_id eda_simulation + +# end EDA_TOOL_SETTINGS(eda_simulation) +# ------------------------------------- + +# ------------------------------- +# start ENTITY(DE10_LITE_Default) + +# end ENTITY(DE10_LITE_Default) +# ----------------------------- + +# -------------------------- +# start ENTITY(vectrex_mist) + + # start DESIGN_PARTITION(Top) + # --------------------------- + + # Incremental Compilation Assignments + # =================================== + set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top + set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top + set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top + + # end DESIGN_PARTITION(Top) + # ------------------------- + +# end ENTITY(vectrex_mist) +# ------------------------ +set_global_assignment -name MIN_CORE_JUNCTION_TEMP 0 +set_global_assignment -name MAX_CORE_JUNCTION_TEMP 85 +set_global_assignment -name VERILOG_INPUT_VERSION SYSTEMVERILOG_2005 +set_global_assignment -name VERILOG_SHOW_LMF_MAPPING_MESSAGES OFF +set_global_assignment -name PHYSICAL_SYNTHESIS_EFFORT EXTRA +set_global_assignment -name CYCLONEII_OPTIMIZATION_TECHNIQUE AREA +set_global_assignment -name SYNTH_TIMING_DRIVEN_SYNTHESIS ON +set_global_assignment -name ENABLE_SIGNALTAP OFF +set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top \ No newline at end of file diff --git a/GCE - Vectrex_MiST/vectrex_MiST.srf b/GCE - Vectrex_MiST/vectrex_MiST.srf new file mode 100644 index 00000000..1c9355aa --- /dev/null +++ b/GCE - Vectrex_MiST/vectrex_MiST.srf @@ -0,0 +1,13 @@ +{ "" "" "" "Verilog HDL or VHDL warning at vectrex.vhd(417): conditional expression evaluates to a constant" { } { } 0 10037 "" 0 0 "Quartus II" 0 -1 0 ""} +{ "" "" "" "VHDL Signal Declaration warning at vectrex.vhd(126): used implicit default value for signal \"video_csync\" because signal was never assigned a value or an explicit default value. Use of implicit default value may introduce unintended design optimizations." { } { } 0 10541 "" 0 0 "Quartus II" 0 -1 0 ""} +{ "" "" "" "*" { } { } 0 10235 "" 0 0 "Quartus II" 0 -1 0 ""} +{ "" "" "" "*" { } { } 0 14284 "" 0 0 "Quartus II" 0 -1 0 ""} +{ "" "" "" "*" { } { } 0 10873 "" 0 0 "Quartus II" 0 -1 0 ""} +{ "" "" "" "*" { } { } 0 10036 "" 0 0 "Quartus II" 0 -1 0 ""} +{ "" "" "" "*" { } { } 0 10273 "" 0 0 "Quartus II" 0 -1 0 ""} +{ "" "" "" "*" { } { } 0 10268 "" 0 0 "Quartus II" 0 -1 0 ""} +{ "" "" "" "*" { } { } 0 10541 "" 0 0 "Quartus II" 0 -1 0 ""} +{ "" "" "" "*" { } { } 0 10492 "" 0 0 "Quartus II" 0 -1 0 ""} +{ "" "" "" "*" { } { } 0 13004 "" 0 0 "Quartus II" 0 -1 0 ""} +{ "" "" "" "*" { } { } 0 13024 "" 0 0 "Quartus II" 0 -1 0 ""} +{ "" "" "" "*" { } { } 0 15705 "" 0 0 "Quartus II" 0 -1 0 ""}