1
0
mirror of https://github.com/Gehstock/Mist_FPGA.git synced 2026-03-25 17:48:46 +00:00

add Vectrex

This commit is contained in:
Gehstock
2018-02-11 08:33:46 +01:00
parent 7f669de9bc
commit 945063ea30
38 changed files with 12151 additions and 0 deletions

View File

@@ -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
---------------------------------------------------------------------------------

Binary file not shown.

View File

@@ -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

View File

@@ -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;

View File

@@ -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

View File

@@ -0,0 +1,2 @@
`define BUILD_DATE "180211"
`define BUILD_TIME "074838"

View File

@@ -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"]

View File

@@ -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

File diff suppressed because it is too large Load Diff

View File

@@ -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;

View File

@@ -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;

View File

@@ -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

View File

@@ -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

View File

@@ -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;

View File

@@ -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 <till@harbaum.org>
//
// 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 <http://www.gnu.org/licenses/>.
//
///////////////////////////////////////////////////////////////////////
//
// 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<<PS2_FIFO_BITS];
reg [PS2_FIFO_BITS-1:0] ps2_kbd_wptr;
reg [PS2_FIFO_BITS-1:0] ps2_kbd_rptr;
// ps2 transmitter state machine
reg [3:0] ps2_kbd_tx_state;
reg [7:0] ps2_kbd_tx_byte;
reg ps2_kbd_parity;
assign ps2_kbd_clk = clk_ps2 || (ps2_kbd_tx_state == 0);
// ps2 transmitter
// Takes a byte from the FIFO and sends it in a ps2 compliant serial format.
reg ps2_kbd_r_inc;
always@(posedge clk_sys) begin
reg old_clk;
old_clk <= clk_ps2;
if(~old_clk & clk_ps2) begin
ps2_kbd_r_inc <= 0;
if(ps2_kbd_r_inc) ps2_kbd_rptr <= ps2_kbd_rptr + 1'd1;
// transmitter is idle?
if(ps2_kbd_tx_state == 0) begin
// data in fifo present?
if(ps2_kbd_wptr != ps2_kbd_rptr) begin
// load tx register from fifo
ps2_kbd_tx_byte <= ps2_kbd_fifo[ps2_kbd_rptr];
ps2_kbd_r_inc <= 1;
// reset parity
ps2_kbd_parity <= 1;
// start transmitter
ps2_kbd_tx_state <= 1;
// put start bit on data line
ps2_kbd_data <= 0; // start bit is 0
end
end else begin
// transmission of 8 data bits
if((ps2_kbd_tx_state >= 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<<PS2_FIFO_BITS];
reg [PS2_FIFO_BITS-1:0] ps2_mouse_wptr;
reg [PS2_FIFO_BITS-1:0] ps2_mouse_rptr;
// ps2 transmitter state machine
reg [3:0] ps2_mouse_tx_state;
reg [7:0] ps2_mouse_tx_byte;
reg ps2_mouse_parity;
assign ps2_mouse_clk = clk_ps2 || (ps2_mouse_tx_state == 0);
// ps2 transmitter
// Takes a byte from the FIFO and sends it in a ps2 compliant serial format.
reg ps2_mouse_r_inc;
always@(posedge clk_sys) begin
reg old_clk;
old_clk <= clk_ps2;
if(~old_clk & clk_ps2) begin
ps2_mouse_r_inc <= 0;
if(ps2_mouse_r_inc) ps2_mouse_rptr <= ps2_mouse_rptr + 1'd1;
// transmitter is idle?
if(ps2_mouse_tx_state == 0) begin
// data in fifo present?
if(ps2_mouse_wptr != ps2_mouse_rptr) begin
// load tx register from fifo
ps2_mouse_tx_byte <= ps2_mouse_fifo[ps2_mouse_rptr];
ps2_mouse_r_inc <= 1;
// reset parity
ps2_mouse_parity <= 1;
// start transmitter
ps2_mouse_tx_state <= 1;
// put start bit on data line
ps2_mouse_data <= 0; // start bit is 0
end
end else begin
// transmission of 8 data bits
if((ps2_mouse_tx_state >= 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

View File

@@ -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<<doublescan))>> 1) + OSD_Y_OFFSET;
wire [9:0] v_osd_end = v_osd_start + (OSD_HEIGHT<<doublescan);
wire [9:0] osd_hcnt = h_cnt - h_osd_start + 1'd1; // one pixel offset for osd_byte register
wire [9:0] osd_vcnt = v_cnt - v_osd_start;
wire osd_de = osd_enable &&
(HSync != hs_pol) && (h_cnt >= 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

View File

@@ -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"]

View File

@@ -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

View File

@@ -0,0 +1,194 @@
//
// scandoubler.v
//
// Copyright (c) 2015 Till Harbaum <till@harbaum.org>
// 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 <http://www.gnu.org/licenses/>.
// 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

View File

@@ -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;

View File

@@ -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;

View File

@@ -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

View File

@@ -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;

View File

@@ -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

View File

@@ -0,0 +1,28 @@
------------------------------------------------------
LINUX build command
------------------------------------------------------
gcc duplicate_byte.c -lm
mv a.out duplicate_byte
gcc make_vhdl_prom.c -lm
mv a.out make_vhdl_prom
------------------------------------------------------
Win32 build command (on linux system)
------------------------------------------------------
i686-w64-mingw32-gcc duplicate_byte.c -lm -m32
mv a.exe duplicate_byte.exe
i686-w64-mingw32-gcc make_vhdl_prom.c -lm -m32
mv a.exe make_vhdl_prom.exe
------------------------------------------------------
Win64 build command (on linux system)
------------------------------------------------------
x86_64-w64-mingw32-gcc duplicate_byte.c -lm
mv a.exe duplicate_byte.exe
x86_64-w64-mingw32-gcc make_vhdl_prom.c -lm
mv a.exe make_vhdl_prom.exe
------------------------------------------------------
------------------------------------------------------

View File

@@ -0,0 +1,37 @@
#include "stdio.h"
#include "stdlib.h"
main (int argc, char **argv)
{
unsigned char byte;
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],"wb");
if (fid_out == NULL)
{
printf("can't open %s\n",argv[2]);
fclose(fid_in);
exit(0);
}
while (fread(&byte,1,1,fid_in)==1)
{
fwrite(&byte,1,1,fid_out);
fwrite(&byte,1,1,fid_out);
}
fclose(fid_in);
fclose(fid_out);
}

View File

@@ -0,0 +1,83 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
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);
}

View File

@@ -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

View File

@@ -0,0 +1,31 @@
# -------------------------------------------------------------------------- #
#
# Copyright (C) 2016 Intel Corporation. All rights reserved.
# Your use of Intel Corporation's design tools, logic functions
# and other software and tools, and its AMPP partner logic
# functions, and any output files from any of the foregoing
# (including device programming or simulation files), and any
# associated documentation or information are expressly subject
# to the terms and conditions of the Intel Program License
# Subscription Agreement, the Intel Quartus Prime License Agreement,
# the Intel MegaCore Function License Agreement, or other
# applicable license agreement, including, without limitation,
# that your use is for the sole purpose of programming logic
# devices manufactured by Intel and sold by Intel or its
# authorized distributors. Please refer to the applicable
# agreement for further details.
#
# -------------------------------------------------------------------------- #
#
# Quartus Prime
# Version 16.1.0 Build 196 10/24/2016 SJ Lite Edition
# Date created = 08:04:28 December 31, 2017
#
# -------------------------------------------------------------------------- #
QUARTUS_VERSION = "16.1"
DATE = "08:04:28 December 31, 2017"
# Revisions
PROJECT_REVISION = "vectrex_MiST"

View File

@@ -0,0 +1,223 @@
# -------------------------------------------------------------------------- #
#
# Copyright (C) 1991-2013 Altera Corporation
# Your use of Altera Corporation's design tools, logic functions
# and other software and tools, and its AMPP partner logic
# functions, and any output files from any of the foregoing
# (including device programming or simulation files), and any
# associated documentation or information are expressly subject
# to the terms and conditions of the Altera Program License
# Subscription Agreement, Altera MegaCore Function License
# Agreement, or other applicable license agreement, including,
# without limitation, that your use is for the sole purpose of
# programming logic devices manufactured by Altera and sold by
# Altera or its authorized distributors. Please refer to the
# applicable agreement for further details.
#
# -------------------------------------------------------------------------- #
#
# Quartus II 64-Bit
# Version 13.1.0 Build 162 10/23/2013 SJ Web Edition
# Date created = 06:03:35 February 11, 2018
#
# -------------------------------------------------------------------------- #
#
# Notes:
#
# 1) The default values for assignments are stored in the file:
# vectrex_MiST_assignment_defaults.qdf
# If this file doesn't exist, see file:
# assignment_defaults.qdf
#
# 2) Altera recommends that you do not modify this file. This
# file is updated automatically by the Quartus II software
# and any changes you make may be lost or overwritten.
#
# -------------------------------------------------------------------------- #
# Project-Wide Assignments
# ========================
set_global_assignment -name ORIGINAL_QUARTUS_VERSION 15.1.0
set_global_assignment -name PROJECT_CREATION_TIME_DATE "17:45:13 JUNE 17,2016"
set_global_assignment -name LAST_QUARTUS_VERSION 13.1
set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files
set_global_assignment -name VHDL_FILE rtl/YM2149_linmix_sep.vhd
set_global_assignment -name VHDL_FILE rtl/vectrex.vhd
set_global_assignment -name VHDL_FILE rtl/m6522a.vhd
set_global_assignment -name VHDL_FILE rtl/gen_ram.vhd
set_global_assignment -name VHDL_FILE rtl/cpu09l_128a.vhd
set_global_assignment -name VHDL_FILE rtl/dac.vhd
set_global_assignment -name SYSTEMVERILOG_FILE rtl/hq2x.sv
set_global_assignment -name VERILOG_FILE rtl/keyboard.v
set_global_assignment -name VERILOG_FILE rtl/mist_io.v
set_global_assignment -name VERILOG_FILE rtl/osd.v
set_global_assignment -name QIP_FILE rtl/pll.qip
set_global_assignment -name VERILOG_FILE rtl/scandoubler.v
set_global_assignment -name SYSTEMVERILOG_FILE rtl/video_mixer.sv
set_global_assignment -name SYSTEMVERILOG_FILE rtl/vectrex_mist.sv
set_global_assignment -name VHDL_FILE rtl/vectrex_exec_prom.vhd
set_global_assignment -name PRE_FLOW_SCRIPT_FILE "quartus_sh:rtl/build_id.tcl"
set_global_assignment -name QIP_FILE rtl/card.qip
# Pin & Location Assignments
# ==========================
set_location_assignment PIN_7 -to LED
set_location_assignment PIN_54 -to CLOCK_27
set_location_assignment PIN_144 -to VGA_R[5]
set_location_assignment PIN_143 -to VGA_R[4]
set_location_assignment PIN_142 -to VGA_R[3]
set_location_assignment PIN_141 -to VGA_R[2]
set_location_assignment PIN_137 -to VGA_R[1]
set_location_assignment PIN_135 -to VGA_R[0]
set_location_assignment PIN_133 -to VGA_B[5]
set_location_assignment PIN_132 -to VGA_B[4]
set_location_assignment PIN_125 -to VGA_B[3]
set_location_assignment PIN_121 -to VGA_B[2]
set_location_assignment PIN_120 -to VGA_B[1]
set_location_assignment PIN_115 -to VGA_B[0]
set_location_assignment PIN_114 -to VGA_G[5]
set_location_assignment PIN_113 -to VGA_G[4]
set_location_assignment PIN_112 -to VGA_G[3]
set_location_assignment PIN_111 -to VGA_G[2]
set_location_assignment PIN_110 -to VGA_G[1]
set_location_assignment PIN_106 -to VGA_G[0]
set_location_assignment PIN_136 -to VGA_VS
set_location_assignment PIN_119 -to VGA_HS
set_location_assignment PIN_65 -to AUDIO_L
set_location_assignment PIN_80 -to AUDIO_R
set_location_assignment PIN_105 -to SPI_DO
set_location_assignment PIN_88 -to SPI_DI
set_location_assignment PIN_126 -to SPI_SCK
set_location_assignment PIN_127 -to SPI_SS2
set_location_assignment PIN_91 -to SPI_SS3
set_location_assignment PIN_13 -to CONF_DATA0
set_location_assignment PIN_49 -to SDRAM_A[0]
set_location_assignment PIN_44 -to SDRAM_A[1]
set_location_assignment PIN_42 -to SDRAM_A[2]
set_location_assignment PIN_39 -to SDRAM_A[3]
set_location_assignment PIN_4 -to SDRAM_A[4]
set_location_assignment PIN_6 -to SDRAM_A[5]
set_location_assignment PIN_8 -to SDRAM_A[6]
set_location_assignment PIN_10 -to SDRAM_A[7]
set_location_assignment PIN_11 -to SDRAM_A[8]
set_location_assignment PIN_28 -to SDRAM_A[9]
set_location_assignment PIN_50 -to SDRAM_A[10]
set_location_assignment PIN_30 -to SDRAM_A[11]
set_location_assignment PIN_32 -to SDRAM_A[12]
set_location_assignment PIN_83 -to SDRAM_DQ[0]
set_location_assignment PIN_79 -to SDRAM_DQ[1]
set_location_assignment PIN_77 -to SDRAM_DQ[2]
set_location_assignment PIN_76 -to SDRAM_DQ[3]
set_location_assignment PIN_72 -to SDRAM_DQ[4]
set_location_assignment PIN_71 -to SDRAM_DQ[5]
set_location_assignment PIN_69 -to SDRAM_DQ[6]
set_location_assignment PIN_68 -to SDRAM_DQ[7]
set_location_assignment PIN_86 -to SDRAM_DQ[8]
set_location_assignment PIN_87 -to SDRAM_DQ[9]
set_location_assignment PIN_98 -to SDRAM_DQ[10]
set_location_assignment PIN_99 -to SDRAM_DQ[11]
set_location_assignment PIN_100 -to SDRAM_DQ[12]
set_location_assignment PIN_101 -to SDRAM_DQ[13]
set_location_assignment PIN_103 -to SDRAM_DQ[14]
set_location_assignment PIN_104 -to SDRAM_DQ[15]
set_location_assignment PIN_58 -to SDRAM_BA[0]
set_location_assignment PIN_51 -to SDRAM_BA[1]
set_location_assignment PIN_85 -to SDRAM_DQMH
set_location_assignment PIN_67 -to SDRAM_DQML
set_location_assignment PIN_60 -to SDRAM_nRAS
set_location_assignment PIN_64 -to SDRAM_nCAS
set_location_assignment PIN_66 -to SDRAM_nWE
set_location_assignment PIN_59 -to SDRAM_nCS
set_location_assignment PIN_33 -to SDRAM_CKE
set_location_assignment PIN_43 -to SDRAM_CLK
set_location_assignment PLL_1 -to "pll:pll|altpll:altpll_component"
# Analysis & Synthesis Assignments
# ================================
set_global_assignment -name FAMILY "Cyclone III"
set_global_assignment -name DEVICE_FILTER_PIN_COUNT 144
set_global_assignment -name DEVICE_FILTER_SPEED_GRADE 8
set_global_assignment -name TOP_LEVEL_ENTITY vectrex_mist
# Fitter Assignments
# ==================
set_global_assignment -name DEVICE EP3C25E144C8
set_global_assignment -name ENABLE_CONFIGURATION_PINS OFF
set_global_assignment -name ENABLE_NCE_PIN OFF
set_global_assignment -name ENABLE_BOOT_SEL_PIN OFF
set_global_assignment -name CYCLONEIII_CONFIGURATION_SCHEME "PASSIVE SERIAL"
set_global_assignment -name CRC_ERROR_OPEN_DRAIN OFF
set_global_assignment -name FORCE_CONFIGURATION_VCCIO ON
set_global_assignment -name STRATIX_DEVICE_IO_STANDARD "3.3-V LVTTL"
set_global_assignment -name CYCLONEII_RESERVE_NCEO_AFTER_CONFIGURATION "USE AS REGULAR IO"
set_global_assignment -name RESERVE_DATA0_AFTER_CONFIGURATION "USE AS REGULAR IO"
set_global_assignment -name RESERVE_DATA1_AFTER_CONFIGURATION "USE AS REGULAR IO"
set_global_assignment -name RESERVE_FLASH_NCE_AFTER_CONFIGURATION "USE AS REGULAR IO"
set_global_assignment -name RESERVE_DCLK_AFTER_CONFIGURATION "USE AS REGULAR IO"
# EDA Netlist Writer Assignments
# ==============================
set_global_assignment -name EDA_SIMULATION_TOOL "<None>"
# 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

View File

@@ -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 ""}