Project

General

Profile

« Previous | Next » 

Revision 115

Added by markw about 11 years ago

First working Chameleon build. No drive emulation, 16KB RAM, PAL.

View differences:

chameleon/atari800core.cdf
/* Quartus II 64-Bit Version 12.1 Build 243 01/31/2013 Service Pack 1.33 SJ Web Edition */
JedecChain;
FileRevision(JESD32A);
DefaultMfr(6E);
P ActionCode(Ign)
Device PartName(CPLD) MfrSpec(OpMask(0));
P ActionCode(Cfg)
Device PartName(EP3C25E144) Path("C:/Users/Mark/Desktop/FPGA/build/output_files/") File("atari800core.sof") MfrSpec(OpMask(1));
ChainEnd;
AlteraBegin;
ChainType(JTAG);
AlteraEnd;
chameleon/atari800core.qsf
# -------------------------------------------------------------------------- #
#
# 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 32-bit
# Version 13.0.1 Build 232 06/12/2013 Service Pack 1 SJ Web Edition
# Date created = 12:05:10 July 13, 2014
#
# -------------------------------------------------------------------------- #
#
# Notes:
#
# 1) The default values for assignments are stored in the file:
# atari800core_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.
#
# -------------------------------------------------------------------------- #
set_global_assignment -name FAMILY "Cyclone III"
set_global_assignment -name DEVICE EP3C25E144C8
set_global_assignment -name TOP_LEVEL_ENTITY atari800core_chameleon
set_global_assignment -name ORIGINAL_QUARTUS_VERSION "13.0 SP1"
set_global_assignment -name PROJECT_CREATION_TIME_DATE "12:05:10 JULY 13, 2014"
set_global_assignment -name LAST_QUARTUS_VERSION "12.1 SP1.33"
set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files
set_global_assignment -name MIN_CORE_JUNCTION_TEMP 0
set_global_assignment -name MAX_CORE_JUNCTION_TEMP 85
set_global_assignment -name DEVICE_FILTER_PIN_COUNT 144
set_global_assignment -name DEVICE_FILTER_SPEED_GRADE 8
set_global_assignment -name ERROR_CHECK_FREQUENCY_DIVISOR 1
set_global_assignment -name CYCLONEII_OPTIMIZATION_TECHNIQUE SPEED
set_global_assignment -name NOMINAL_CORE_SUPPLY_VOLTAGE 1.2V
set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top
set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top
set_global_assignment -name LL_ROOT_REGION ON -section_id "Root Region"
set_global_assignment -name LL_MEMBER_STATE LOCKED -section_id "Root Region"
set_instance_assignment -name MULTICYCLE 2 -from "cpu_6510:my6510|cpu65xx:cpuInstance|*" -to "cpu_6510:my6510|cpu65xx:cpuInstance|*"
set_location_assignment PIN_111 -to red[0]
set_location_assignment PIN_110 -to red[1]
set_location_assignment PIN_106 -to red[2]
set_location_assignment PIN_105 -to red[3]
set_location_assignment PIN_104 -to red[4]
set_location_assignment PIN_103 -to grn[0]
set_location_assignment PIN_101 -to grn[1]
set_location_assignment PIN_100 -to grn[2]
set_location_assignment PIN_99 -to grn[3]
set_location_assignment PIN_98 -to grn[4]
set_location_assignment PIN_112 -to blu[0]
set_location_assignment PIN_133 -to blu[1]
set_location_assignment PIN_135 -to blu[2]
set_location_assignment PIN_136 -to blu[3]
set_location_assignment PIN_137 -to blu[4]
set_location_assignment PIN_44 -to sd_clk
set_location_assignment PIN_42 -to sd_addr[12]
set_location_assignment PIN_33 -to sd_addr[11]
set_location_assignment PIN_144 -to sd_addr[10]
set_location_assignment PIN_31 -to sd_addr[9]
set_location_assignment PIN_28 -to sd_addr[8]
set_location_assignment PIN_11 -to sd_addr[7]
set_location_assignment PIN_10 -to sd_addr[6]
set_location_assignment PIN_8 -to sd_addr[5]
set_location_assignment PIN_7 -to sd_addr[4]
set_location_assignment PIN_30 -to sd_addr[3]
set_location_assignment PIN_32 -to sd_addr[2]
set_location_assignment PIN_6 -to sd_addr[1]
set_location_assignment PIN_4 -to sd_addr[0]
set_location_assignment PIN_39 -to sd_ba_0
set_location_assignment PIN_143 -to sd_ba_1
set_location_assignment PIN_50 -to sd_we_n
set_location_assignment PIN_43 -to sd_ras_n
set_location_assignment PIN_46 -to sd_cas_n
set_location_assignment PIN_76 -to sd_data[15]
set_location_assignment PIN_77 -to sd_data[14]
set_location_assignment PIN_72 -to sd_data[13]
set_location_assignment PIN_69 -to sd_data[12]
set_location_assignment PIN_67 -to sd_data[11]
set_location_assignment PIN_65 -to sd_data[10]
set_location_assignment PIN_60 -to sd_data[9]
set_location_assignment PIN_58 -to sd_data[8]
set_location_assignment PIN_59 -to sd_data[7]
set_location_assignment PIN_64 -to sd_data[6]
set_location_assignment PIN_66 -to sd_data[5]
set_location_assignment PIN_68 -to sd_data[4]
set_location_assignment PIN_71 -to sd_data[3]
set_location_assignment PIN_79 -to sd_data[2]
set_location_assignment PIN_80 -to sd_data[1]
set_location_assignment PIN_83 -to sd_data[0]
set_location_assignment PIN_51 -to sd_ldqm
set_location_assignment PIN_49 -to sd_udqm
set_location_assignment PIN_25 -to clk8
set_location_assignment PIN_142 -to nHSync
set_location_assignment PIN_141 -to nVSync
set_location_assignment PIN_87 -to mux_clk
set_location_assignment PIN_119 -to mux[0]
set_location_assignment PIN_115 -to mux[1]
set_location_assignment PIN_114 -to mux[2]
set_location_assignment PIN_113 -to mux[3]
set_location_assignment PIN_125 -to mux_d[0]
set_location_assignment PIN_121 -to mux_d[1]
set_location_assignment PIN_120 -to mux_d[2]
set_location_assignment PIN_132 -to mux_d[3]
set_location_assignment PIN_126 -to mux_q[0]
set_location_assignment PIN_127 -to mux_q[1]
set_location_assignment PIN_128 -to mux_q[2]
set_location_assignment PIN_129 -to mux_q[3]
set_location_assignment PIN_86 -to sigmaL
set_location_assignment PIN_85 -to sigmaR
set_location_assignment PIN_89 -to dotclock_n
set_location_assignment PIN_88 -to phi2_n
set_location_assignment PIN_91 -to romlh_n
set_location_assignment PIN_90 -to ioef_n
set_location_assignment PIN_13 -to spi_miso
set_location_assignment PIN_22 -to mmc_cd_n
set_location_assignment PIN_24 -to mmc_wp
set_location_assignment PIN_52 -to usart_tx
set_location_assignment PIN_53 -to usart_clk
set_location_assignment PIN_54 -to usart_rts
set_location_assignment PIN_55 -to usart_cts
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to sd_addr[12]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to sd_addr[0]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to sd_addr[11]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to sd_addr[10]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to sd_addr[9]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to sd_addr[8]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to sd_addr[7]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to sd_addr[6]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to sd_addr[5]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to sd_addr[4]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to sd_addr[3]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to sd_addr[2]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to sd_addr[1]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to sd_ba_0
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to sd_ba_1
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to sd_cas_n
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to sd_clk
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to sd_ldqm
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to sd_ras_n
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to sd_udqm
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to sd_we_n
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to sd_data[15]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to sd_data[15]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to sd_data[14]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to sd_data[14]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to sd_data[13]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to sd_data[13]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to sd_data[12]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to sd_data[12]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to sd_data[11]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to sd_data[11]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to sd_data[10]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to sd_data[10]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to sd_data[9]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to sd_data[9]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to sd_data[8]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to sd_data[8]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to sd_data[7]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to sd_data[6]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to sd_data[5]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to sd_data[4]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to sd_data[3]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to sd_data[2]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to sd_data[1]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to sd_data[0]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to sd_data[7]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to sd_data[6]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to sd_data[5]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to sd_data[4]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to sd_data[3]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to sd_data[2]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to sd_data[1]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to sd_data[0]
set_location_assignment PIN_23 -to freeze_n
set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top
set_global_assignment -name CDF_FILE atari800core.cdf
set_global_assignment -name VHDL_FILE chameleon_docking_station.vhd
set_global_assignment -name VHDL_FILE chameleon_1mhz.vhd
set_global_assignment -name VHDL_FILE chameleon_1khz.vhd
set_global_assignment -name VHDL_FILE chameleon_led.vhd
set_global_assignment -name VHDL_FILE chameleon_phi_clock_e.vhd
set_global_assignment -name VHDL_FILE chameleon_phi_clock_a.vhd
set_global_assignment -name VHDL_FILE atari800core_chameleon.vhd
set_global_assignment -name QIP_FILE pll.qip
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"
set_global_assignment -name CYCLONEII_RESERVE_NCEO_AFTER_CONFIGURATION "USE AS REGULAR IO"
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
chameleon/atari800core.sdc
create_clock -period 8MHz [get_ports CLK8]
derive_pll_clocks
derive_clock_uncertainty
chameleon/atari800core_chameleon.vhd
---------------------------------------------------------------------------
-- (c) 2014 mark watson
-- I am happy for anyone to use this for non-commercial use.
-- If my vhdl files are used commercially or otherwise sold,
-- please contact me for explicit permission at scrameta (gmail).
-- This applies for source and binary form and derived works.
---------------------------------------------------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.all;
use ieee.numeric_std.all;
LIBRARY work;
entity atari800core_chameleon is
port
(
-- VGA
red : OUT STD_LOGIC_VECTOR(4 downto 0);
grn : OUT STD_LOGIC_VECTOR(4 downto 0);
blu : OUT STD_LOGIC_VECTOR(4 downto 0);
nHSync: OUT STD_LOGIC;
nVSync: OUT STD_LOGIC;
-- SDRAM
sd_clk : OUT STD_LOGIC;
sd_addr : OUT STD_LOGIC_VECTOR(12 downto 0);
sd_ba_0 : OUT STD_LOGIC;
sd_ba_1 : OUT STD_LOGIC;
sd_we_n : OUT STD_LOGIC;
sd_ras_n : OUT STD_LOGIC;
sd_cas_n : OUT STD_LOGIC;
sd_data :INOUT STD_LOGIC_VECTOR(15 downto 0);
sd_ldqm : OUT STD_LOGIC;
sd_udqm : OUT STD_LOGIC;
-- Clocks
clk8 : in std_logic;
phi2_n : in std_logic;
dotclock_n : in std_logic;
-- Bus
romlh_n : in std_logic;
ioef_n : in std_logic;
-- Buttons
freeze_n : in std_logic;
-- MMC/SPI
spi_miso : in std_logic;
mmc_cd_n : in std_logic;
mmc_wp : in std_logic;
-- mosi is on the MUX...
-- MUX CPLD
mux_clk : out std_logic;
mux : out unsigned(3 downto 0);
mux_d : out unsigned(3 downto 0);
mux_q : in unsigned(3 downto 0);
-- USART
usart_tx : in std_logic;
usart_clk : in std_logic;
usart_rts : in std_logic;
usart_cts : in std_logic;
-- Audio
sigmaL : out std_logic;
sigmaR : out std_logic
);
end atari800core_chameleon;
architecture vhdl of atari800core_chameleon is
component hq_dac
port (
reset :in std_logic;
clk :in std_logic;
clk_ena : in std_logic;
pcm_in : in std_logic_vector(19 downto 0);
dac_out : out std_logic
);
end component;
signal AUDIO_L_RAW : std_logic_vector(15 downto 0);
signal AUDIO_R_RAW : std_logic_vector(15 downto 0);
signal VGA_VS_RAW : std_logic;
signal VGA_HS_RAW : std_logic;
signal RESET_n : std_logic;
signal PLL_LOCKED : std_logic;
signal CLK : std_logic;
-- MUX
signal mux_clk_reg : std_logic := '0';
signal mux_reg : unsigned(3 downto 0) := (others => '1');
signal mux_d_reg : unsigned(3 downto 0) := (others => '1');
-- LEDs
signal led_green : std_logic;
signal led_red : std_logic;
-- clocks...
signal sysclk : std_logic;
signal ena_1mhz : std_logic;
signal ena_1khz : std_logic;
signal phi2 : std_logic;
signal no_clock : std_logic;
-- Docking station
signal docking_station : std_logic;
signal docking_ena : std_logic;
signal docking_irq : std_logic;
signal irq_n : std_logic;
signal docking_joystick1 : unsigned(5 downto 0);
signal docking_joystick2 : unsigned(5 downto 0);
signal docking_joystick3 : unsigned(5 downto 0);
signal docking_joystick4 : unsigned(5 downto 0);
-- PS/2 Keyboard
signal ps2_keyboard_clk_in : std_logic;
signal ps2_keyboard_dat_in : std_logic;
--signal ps2_keyboard_clk_out : std_logic;
--signal ps2_keyboard_dat_out : std_logic;
begin
RESET_N <= PLL_LOCKED;
-- disable unused parts
-- sdram
sd_clk <= 'Z';
sd_addr <= (others=>'0');
sd_ba_0 <= '0';
sd_ba_1 <= '0';
sd_we_n <= '1';
sd_ras_n <= '1';
sd_cas_n <= '1';
sd_data <= (others=>'Z');
sd_ldqm <= '0';
sd_udqm <= '0';
-- simplest possible implementation
-- pll
pll : ENTITY work.pll
PORT MAP
(
inclk0 => clk8,
c0 => clk,
locked => pll_locked
);
-- core
atari800core : ENTITY work.atari800core_helloworld
GENERIC MAP
(
cycle_length => 32,
video_bits => 5,
internal_rom => 1,
internal_ram => 16384
)
PORT MAP
(
CLK => clk,
RESET_N => RESET_N,
-- VIDEO OUT - PAL/NTSC, original Atari timings approx (may be higher res)
VIDEO_VS => vga_vs_raw,
VIDEO_HS => vga_hs_raw,
VIDEO_B => blu,
VIDEO_G => grn,
VIDEO_R => red,
-- AUDIO OUT - Pokey/GTIA 1-bit and Covox all mixed
AUDIO_L => audio_l_raw,
AUDIO_R => audio_r_raw,
-- JOYSTICK
JOY1_n => std_logic_vector(docking_joystick1)(4 downto 0),
JOY2_n => std_logic_vector(docking_joystick2)(4 downto 0),
-- KEYBOARD
PS2_CLK => ps2_keyboard_clk_in,
PS2_DAT => ps2_keyboard_dat_in,
-- video standard
PAL => '1'
);
-- video glue
nHSync <= (VGA_HS_RAW xor VGA_VS_RAW);
nVSync <= (VGA_VS_RAW);
-- audio glue
dac_left : hq_dac
port map
(
reset => not(reset_n),
clk => clk,
clk_ena => '1',
pcm_in => AUDIO_L_RAW&"0000",
dac_out => sigmaL
);
dac_right : hq_dac
port map
(
reset => not(reset_n),
clk => clk,
clk_ena => '1',
pcm_in => AUDIO_R_RAW&"0000",
dac_out => sigmaR
);
-- Some common chameleon parts - e.g. mux - taken from the hardware test
sysclk <= clk;
-- -----------------------------------------------------------------------
-- 1 Mhz and 1 Khz clocks
-- -----------------------------------------------------------------------
my1Mhz : entity work.chameleon_1mhz
generic map (
--clk_ticks_per_usec => 100
clk_ticks_per_usec => 57
)
port map (
clk => sysclk,
ena_1mhz => ena_1mhz,
ena_1mhz_2 => open
);
my1Khz : entity work.chameleon_1khz
port map (
clk => sysclk,
ena_1mhz => ena_1mhz,
ena_1khz => ena_1khz
);
-- -----------------------------------------------------------------------
-- Phi 2
-- -----------------------------------------------------------------------
myPhi2: entity work.chameleon_phi_clock
port map (
clk => sysclk,
phiIn => phi2,
-- no_clock is high when there are no phiIn changes detected.
-- This signal allows switching between real I/O and internal emulation.
no_clock => no_clock,
-- docking_station is high when there are no phiIn changes (no_clock) and
-- the phi signal is low. Without docking station phi is pulled up.
docking_station => docking_station
);
phi2 <= not phi2_n;
-- -----------------------------------------------------------------------
-- Docking station
-- -----------------------------------------------------------------------
myDockingStation : entity work.chameleon_docking_station
port map (
clk => sysclk,
ena_1mhz => ena_1mhz,
enable => docking_ena,
docking_station => docking_station,
dotclock_n => dotclock_n,
io_ef_n => ioef_n,
rom_lh_n => romlh_n,
irq_d => irq_n,
irq_q => docking_irq,
joystick1 => docking_joystick1,
joystick2 => docking_joystick2,
joystick3 => docking_joystick3,
joystick4 => docking_joystick4,
keys => open,
restore_key_n => open,
amiga_power_led => '0',
amiga_drive_led => '0',
amiga_reset_n => open,
amiga_scancode => open
);
-- -----------------------------------------------------------------------
-- MUX CPLD
-- -----------------------------------------------------------------------
-- MUX clock
process(sysclk)
begin
if rising_edge(sysclk) then
mux_clk_reg <= not mux_clk_reg;
end if;
end process;
-- MUX read
process(sysclk)
begin
if rising_edge(sysclk) then
if mux_clk_reg = '1' then
case mux_reg is
when X"6" =>
irq_n <= mux_q(2);
when X"B" =>
--reset_button_n <= mux_q(1);
--ir <= mux_q(3);
when X"A" =>
--vga_id <= mux_q;
when X"E" =>
ps2_keyboard_dat_in <= mux_q(0);
ps2_keyboard_clk_in <= mux_q(1);
--ps2_mouse_dat_in <= mux_q(2);
--ps2_mouse_clk_in <= mux_q(3);
when others =>
null;
end case;
end if;
end if;
end process;
-- MUX write
process(sysclk)
begin
if rising_edge(sysclk) then
docking_ena <= '0';
if mux_clk_reg = '1' then
case mux_reg is
when X"7" =>
mux_d_reg <= "1111";
if docking_station = '1' then
mux_d_reg <= "1" & docking_irq & "11";
end if;
mux_reg <= X"6";
when X"6" =>
mux_d_reg <= "1111";
mux_reg <= X"8";
when X"8" =>
mux_d_reg <= "1111";
mux_reg <= X"A";
when X"A" =>
mux_d_reg <= "10" & led_green & led_red;
mux_reg <= X"B";
when X"B" =>
--mux_d_reg <= iec_reg;
mux_d_reg <= "1111";
mux_reg <= X"D";
docking_ena <= '1';
when X"D" =>
--mux_d_reg(0) <= ps2_keyboard_dat_out;
--mux_d_reg(1) <= ps2_keyboard_clk_out;
--mux_d_reg(2) <= ps2_mouse_dat_out;
--mux_d_reg(3) <= ps2_mouse_clk_out;
mux_d_reg <= "1111";
mux_reg <= X"E";
when X"E" =>
mux_d_reg <= "1111";
mux_reg <= X"7";
when others =>
mux_reg <= X"B";
mux_d_reg <= "10" & led_green & led_red;
end case;
end if;
end if;
end process;
mux_clk <= mux_clk_reg;
mux_d <= mux_d_reg;
mux <= mux_reg;
-- -----------------------------------------------------------------------
-- LEDs
-- -----------------------------------------------------------------------
myGreenLed : entity work.chameleon_led
port map (
clk => sysclk,
clk_1khz => ena_1khz,
led_on => '0',
led_blink => '1',
led => led_red,
led_1hz => led_green
);
end vhdl;
chameleon/build.sh
rm -rf build
mkdir build
cp atari800core_chameleon.vhd build
cp pll.* build
cp atari800core.sdc build
cp atari800core.cdf build
cp chameleon_* build
mkdir build/common
mkdir build/common/a8core
mkdir build/common/components
cp ../common/a8core/* ./build/common/a8core
cp ../common/components/* ./build/common/components
cd build
../makeqsf ../atari800core.qsf ./common/a8core ./common/components
quartus_sh --flow compile atari800core
chameleon/chameleon_1khz.vhd
-- -----------------------------------------------------------------------
--
-- Turbo Chameleon
--
-- Multi purpose FPGA expansion for the Commodore 64 computer
--
-- -----------------------------------------------------------------------
-- Copyright 2005-2011 by Peter Wendrich (pwsoft@syntiac.com)
-- http://www.syntiac.com/chameleon.html
--
-- This source file is free software: you can redistribute it and/or modify
-- it under the terms of the GNU Lesser 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/>.
--
-- -----------------------------------------------------------------------
--
-- 1 Khz clock source
--
-- -----------------------------------------------------------------------
-- clk - system clock input
-- ena_1mhz - 1 Mhz input, signal must be one cycle high each micro-second.
-- ena_1khz - 1 Khz output. Signal is one cycle '1' each 1 millisecond.
-- -----------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.all;
-- -----------------------------------------------------------------------
entity chameleon_1khz is
port (
clk : in std_logic;
ena_1mhz : in std_logic;
ena_1khz : out std_logic
);
end entity;
-- -----------------------------------------------------------------------
architecture rtl of chameleon_1khz is
constant maxcount : integer := 999;
signal cnt : integer range 0 to maxcount := maxcount;
signal ena_out : std_logic := '0';
begin
ena_1khz <= ena_out;
process(clk)
begin
if rising_edge(clk) then
ena_out <= '0';
if ena_1mhz = '1' then
if cnt = 0 then
cnt <= maxcount;
ena_out <= '1';
else
cnt <= cnt - 1;
end if;
end if;
end if;
end process;
end architecture;
chameleon/chameleon_1mhz.vhd
-- -----------------------------------------------------------------------
--
-- Turbo Chameleon
--
-- Multi purpose FPGA expansion for the Commodore 64 computer
--
-- -----------------------------------------------------------------------
-- Copyright 2005-2011 by Peter Wendrich (pwsoft@syntiac.com)
-- http://www.syntiac.com/chameleon.html
--
-- This source file is free software: you can redistribute it and/or modify
-- it under the terms of the GNU Lesser 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/>.
--
-- -----------------------------------------------------------------------
--
-- 1 Mhz clock source
--
-- -----------------------------------------------------------------------
-- clk - system clock input
-- ena_1mhz - 1 Mhz output. Signal is one cycle '1' each micro-second.
-- -----------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.all;
-- -----------------------------------------------------------------------
entity chameleon_1mhz is
generic (
-- Timer calibration. Clock speed in Mhz.
clk_ticks_per_usec : integer
);
port (
clk : in std_logic;
ena_1mhz : out std_logic;
ena_1mhz_2 : out std_logic
);
end entity;
-- -----------------------------------------------------------------------
architecture rtl of chameleon_1mhz is
constant maxcount : integer := clk_ticks_per_usec-1;
signal cnt : integer range 0 to maxcount := maxcount;
signal ena_out : std_logic := '0';
signal ena2_out : std_logic := '0';
begin
ena_1mhz <= ena_out;
ena_1mhz_2 <= ena2_out;
process(clk)
begin
if rising_edge(clk) then
ena_out <= '0';
if cnt = 0 then
cnt <= maxcount;
ena_out <= '1';
else
cnt <= cnt - 1;
end if;
end if;
end process;
process(clk)
begin
if rising_edge(clk) then
ena2_out <= '0';
if cnt = (maxcount / 2) then
ena2_out <= '1';
end if;
end if;
end process;
end architecture;
chameleon/chameleon_docking_station.vhd
-- -----------------------------------------------------------------------
--
-- Turbo Chameleon
--
-- Multi purpose FPGA expansion for the Commodore 64 computer
--
-- -----------------------------------------------------------------------
-- Copyright 2005-2011 by Peter Wendrich (pwsoft@syntiac.com)
-- All Rights Reserved.
--
-- http://www.syntiac.com/chameleon.html
-- -----------------------------------------------------------------------
--
-- Chameleon docking station
--
-- -----------------------------------------------------------------------
-- clk - system clock
-- enable - must be cycle high to advance statemachine (sync with MUX)
-- ena_1mhz - must be one cycle high each micro-second. Used for timers.
-- -----------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.all;
-- -----------------------------------------------------------------------
entity chameleon_docking_station is
port (
clk : in std_logic;
enable : in std_logic;
ena_1mhz : in std_logic;
docking_station : in std_logic;
dotclock_n : in std_logic;
io_ef_n : in std_logic;
rom_lh_n : in std_logic;
irq_d : in std_logic;
irq_q : out std_logic;
joystick1 : out unsigned(5 downto 0);
joystick2 : out unsigned(5 downto 0);
joystick3 : out unsigned(5 downto 0);
joystick4 : out unsigned(5 downto 0);
-- 0 = col0, row0
-- 1 = col1, row0
-- 8 = col0, row1
-- 63 = col7, row7
keys : out unsigned(63 downto 0);
restore_key_n : out std_logic;
-- Amiga keyboard
amiga_power_led : in std_logic;
amiga_drive_led : in std_logic;
amiga_reset_n : out std_logic;
amiga_trigger : out std_logic;
amiga_scancode : out unsigned(7 downto 0)
);
end entity;
-- -----------------------------------------------------------------------
architecture rtl of chameleon_docking_station is
constant shift_reg_bits : integer := 13*8;
signal shift_reg : unsigned(shift_reg_bits-1 downto 0);
signal bit_cnt : unsigned(7 downto 0) := (others => '0');
signal once : std_logic := '0';
signal key_reg : unsigned(63 downto 0) := (others => '1');
signal restore_n_reg : std_logic := '1';
signal joystick1_reg : unsigned(5 downto 0) := (others => '0');
signal joystick2_reg : unsigned(5 downto 0) := (others => '0');
signal joystick3_reg : unsigned(5 downto 0) := (others => '0');
signal joystick4_reg : unsigned(5 downto 0) := (others => '0');
signal dotclock_n_reg : std_logic := '0';
signal dotclock_n_dly : std_logic := '0';
signal io_ef_n_reg : std_logic := '0';
signal rom_lh_n_reg : std_logic := '1';
signal irq_q_reg : std_logic := '1';
signal amiga_reset_n_reg : std_logic := '0';
signal amiga_trigger_reg : std_logic := '0';
signal amiga_scancode_reg : unsigned(7 downto 0) := (others => '0');
begin
joystick1 <= joystick1_reg;
joystick2 <= joystick2_reg;
joystick3 <= joystick3_reg;
joystick4 <= joystick4_reg;
keys <= key_reg;
restore_key_n <= restore_n_reg;
amiga_reset_n <= amiga_reset_n_reg;
amiga_trigger <= amiga_trigger_reg;
amiga_scancode <= amiga_scancode_reg;
irq_q <= irq_q_reg;
--
-- Sample DotClock, IO_EF and ROM_LH input.
process(clk) is
begin
if rising_edge(clk) then
dotclock_n_reg <= dotclock_n;
dotclock_n_dly <= dotclock_n_reg;
io_ef_n_reg <= io_ef_n;
rom_lh_n_reg <= rom_lh_n;
end if;
end process;
--
-- Receive serial stream
process(clk) is
begin
if rising_edge(clk) then
if (dotclock_n_reg = '0') and (dotclock_n_dly = '1') then
shift_reg <= (not rom_lh_n_reg) & shift_reg(shift_reg'high downto 1);
bit_cnt <= bit_cnt + 1;
end if;
if (io_ef_n_reg = '1') and (bit_cnt >= shift_reg_bits) then
-- Word trigger. Signals start of serial bit-stream.
bit_cnt <= (others => '0');
end if;
end if;
end process;
--
-- Amiga keyboard LED control
process(clk) is
begin
if rising_edge(clk) then
irq_q_reg <= '1';
if (bit_cnt >= 40) and (bit_cnt < 56) then
irq_q_reg <= amiga_power_led;
end if;
if (bit_cnt >= 72) and (bit_cnt < 88) then
irq_q_reg <= amiga_drive_led;
end if;
end if;
end process;
--
-- Decode bytes
process(clk) is
begin
if rising_edge(clk) then
if bit_cnt = shift_reg_bits then
-- Map shifted bits to joysticks
joystick1_reg <= shift_reg(101 downto 96);
joystick2_reg <= shift_reg(85 downto 80);
joystick3_reg <= shift_reg(102)& shift_reg(103) & shift_reg(92) & shift_reg(93) & shift_reg(94) & shift_reg(95);
joystick4_reg <= shift_reg(86) & shift_reg(87) & shift_reg(88) & shift_reg(89) & shift_reg(90) & shift_reg(91);
restore_n_reg <= shift_reg(1);
-- Map shifted bits to C64 keyboard
if (shift_reg(87 downto 80) = X"FF") and (shift_reg(103 downto 96) = X"FF") then
for row in 0 to 7 loop
for col in 0 to 7 loop
-- uC scans column wise.
key_reg(row*8 + col) <= shift_reg(16 + col*8 + row);
end loop;
end loop;
else
-- Prevent conflict between keyboard and joystick.
-- Relase all keyboard keys while joystick button(s) are pressed.
key_reg <= (others => '1');
end if;
-- Amiga keyboard
amiga_reset_n_reg <= shift_reg(2);
if shift_reg(0) = '1' then
amiga_scancode_reg <= shift_reg(15 downto 8);
amiga_trigger_reg <= once;
end if;
once <= '0';
end if;
if (io_ef_n_reg = '1') then
once <= '1';
end if;
-- No docking station connected.
-- Disable all outputs to prevent conflicts.
if docking_station = '0' then
joystick1_reg <= (others => '1');
joystick2_reg <= (others => '1');
joystick3_reg <= (others => '1');
joystick4_reg <= (others => '1');
key_reg <= (others => '1');
restore_n_reg <= '1';
amiga_reset_n_reg <= '1';
end if;
end if;
end process;
end architecture;
chameleon/chameleon_led.vhd
-- -----------------------------------------------------------------------
--
-- Turbo Chameleon
--
-- Multi purpose FPGA expansion for the Commodore 64 computer
--
-- -----------------------------------------------------------------------
-- Copyright 2005-2011 by Peter Wendrich (pwsoft@syntiac.com)
-- All Rights Reserved.
--
-- Your allowed to re-use this file for non-commercial applications
-- developed for the Turbo Chameleon 64 cartridge. Either open or closed
-- source whatever might be required by other licenses.
--
-- http://www.syntiac.com/chameleon.html
-- -----------------------------------------------------------------------
--
-- LED blinker. Blink frequency 2 Hz
--
-- -----------------------------------------------------------------------
-- clk - system clock input
-- clk_1khz - 1 Khz clock input
-- led_on - if high the LED is on
-- led_blink - if high the LED is blinking
-- led - led output (high is on) 2hz
-- led_1hz - led output 1 hz
-- -----------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.all;
-- -----------------------------------------------------------------------
entity chameleon_led is
port (
clk : in std_logic;
clk_1khz : in std_logic;
led_on : in std_logic;
led_blink : in std_logic;
led : out std_logic;
led_1hz : out std_logic
);
end entity;
-- -----------------------------------------------------------------------
architecture rtl of chameleon_led is
signal count : unsigned(9 downto 0);
begin
led <= count(8);
led_1hz <= count(9);
process(clk)
begin
if rising_edge(clk) then
if clk_1khz = '1' then
count <= count + 1;
end if;
if led_blink = '0' then
count(8) <= led_on;
count(9) <= led_on;
end if;
end if;
end process;
end architecture;
chameleon/chameleon_phi_clock_a.vhd
-- -----------------------------------------------------------------------
--
-- VGA-64
--
-- Multi purpose FPGA expansion for the Commodore 64 computer
--
-- -----------------------------------------------------------------------
-- Copyright 2005-2010 by Peter Wendrich (pwsoft@syntiac.com)
-- http://www.syntiac.com/chameleon.html
-- -----------------------------------------------------------------------
--
-- C64 Phi2-clock regeneration and divider
--
-- -----------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.all;
-- -----------------------------------------------------------------------
architecture rtl of chameleon_phi_clock is
--constant phaseShift : integer := 5; -- Number of cycles that FPGA runs ahead of measured phi.
constant phaseShift : integer := 8; -- Number of cycles that FPGA runs ahead of measured phi.
constant guardBits : integer := 4; -- Extra bits to reduce rounding errors in calculations
signal phiReg1 : std_logic;
signal phiReg2 : std_logic;
signal phiReg3 : std_logic;
signal phiSync : boolean;
signal locCnt : unsigned(7 downto 0) := (others => '0');
signal fracCnt : unsigned(guardBits-1 downto 0) := (others => '0');
signal c64Cnt : unsigned(7 downto 0) := (others => '0');
signal slvCnt : unsigned(7 downto 0) := (others => '0');
signal avgDelta : signed(8 downto 0) := (others => '0');
signal avgLen : unsigned((7+guardBits) downto 0) := (others => '0');
signal localPreHalf : std_logic := '0';
signal localHalf : std_logic := '0';
signal localPreEnd : std_logic := '0';
signal localEnd : std_logic := '0';
signal localPhi : std_logic := '0';
signal localPost1 : std_logic := '0';
signal localPost2 : std_logic := '0';
signal localPost3 : std_logic := '0';
signal localPost4 : std_logic := '0';
begin
-- Copy of input phi (deglitched)
phiBuffer <= phiReg3;
-- Average phi length
phiLength <= avgLen((7+guardBits) downto guardBits);
-- Local generated phi
phiLocal <= localPhi;
-- Cycle counter (add 1 to max-counter for each Mhz system clock)
-- For 100Mhz the cycle-counter runs to about 97 (NTSC) or 102 (PAL)
phiCnt <= locCnt;
phiPreHalf <= localPreHalf;
phiHalf <= localHalf;
phiPreEnd <= localPreEnd;
phiEnd <= localEnd;
phiPost1 <= localPost1;
phiPost2 <= localPost2;
phiPost3 <= localPost3;
phiPost4 <= localPost4;
-- Input clock synchronizer
process(clk) is
begin
if rising_edge(clk) then
phiReg1 <= phiIn;
phiReg2 <= phiReg1;
phiReg3 <= phiReg2;
end if;
end process;
phiSync <= (phiReg1 = '0') and (phiReg2 = '0') and (phiReg3 = '1');
-- Determine cycle length
process(clk) is
begin
if rising_edge(clk) then
no_clock <= '0';
docking_station <= '0';
avgDelta <= (others => '0');
avgLen <= unsigned(signed(avgLen) + avgDelta);
if (not c64Cnt) /= 0 then
c64Cnt <= c64Cnt + 1;
else
-- No Sync? Use internal speed.
-- Values for avgLen are determined experimentally using the testbench to measure actually speed.
-- Higher numbers slow down clock. Lower numbers speed clock up. Try a few times until optimum is reached
-- for particular system clock (100 Mhz at time of writing). Clocks can be accurate to atleast 3 digits with 4 guard bits.
-- PAL mode 0.985248 Mhz
avgLen <= to_unsigned(1703, 8+guardBits);
if mode = '1' then
-- NTSC mode 1.022727 Mhz
avgLen <= to_unsigned(1643, 8+guardBits);
end if;
if (phiReg1 = '0') and (phiReg2 = '0') and (phiReg3 = '0') then
docking_station <= '1';
end if;
no_clock <= '1';
end if;
if phiSync then
avgDelta <= signed("0" & c64Cnt) - signed("0" & avgLen((7+guardBits) downto guardBits));
c64Cnt <= (others => '0');
end if;
end if;
end process;
process(clk) is
begin
if rising_edge(clk) then
localPost1 <= localHalf or localEnd;
localPost2 <= localPost1;
localPost3 <= localPost2;
localPost4 <= localPost3;
end if;
end process;
process(clk) is
variable newFrac : unsigned(fracCnt'high+1 downto fracCnt'low);
begin
if rising_edge(clk) then
localPreHalf <= '0';
localHalf <= localPreHalf;
localPreEnd <= '0';
localEnd <= localPreEnd;
locCnt <= locCnt + 1;
if slvCnt >= avgLen((7+guardBits) downto guardBits) then
slvCnt <= (others => '0');
else
slvCnt <= slvCnt + 1;
end if;
if (slvCnt + phaseShift) = avgLen((7+guardBits) downto (1+guardBits)) then
localPreHalf <= '1';
end if;
if (slvCnt + phaseShift) = avgLen((7+guardBits) downto guardBits)
and localPhi = '1' then
localPreEnd <= '1';
end if;
if localHalf = '1' then
localPhi <= '1';
end if;
if localEnd = '1' then
-- Add fractional part to clock counter to have higher precision
newFrac := ("0" & fracCnt) + ("0" & (not avgLen(guardBits-1 downto 0)));
fracCnt <= newFrac(fracCnt'range);
localPhi <= '0';
locCnt <= (others => '0');
slvCnt <= c64Cnt + ("0000000" & newFrac(newFrac'high));
end if;
end if;
end process;
end architecture;
chameleon/chameleon_phi_clock_e.vhd
-- -----------------------------------------------------------------------
--
-- VGA-64
--
-- Multi purpose FPGA expansion for the Commodore 64 computer
--
-- -----------------------------------------------------------------------
-- Copyright 2005-2010 by Peter Wendrich (pwsoft@syntiac.com)
-- http://www.syntiac.com/chameleon.html
-- -----------------------------------------------------------------------
--
-- C64 Phi2-clock regeneration and divider
--
-- -----------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.all;
-- -----------------------------------------------------------------------
entity chameleon_phi_clock is
port (
clk : in std_logic;
phiIn : in std_logic;
-- Standalone mode, 0=PAL and 1=NTSC
mode : in std_logic := '0';
-- Buffered phiIn (delayed)
phiBuffer : out std_logic;
phiLength : out unsigned(7 downto 0);
-- no_clock is high when there are no phiIn changes detected.
-- This signal allows switching between real I/O and internal emulation.
no_clock : out std_logic;
-- docking_station is high when there are no phiIn changes (no_clock) and
-- the phi signal is low. Without docking station phi is pulled up.
docking_station : out std_logic;
-- Resynthesised Phi2 clock
phiLocal : out std_logic;
-- Cycle counter
phiCnt : out unsigned(7 downto 0);
-- Control pulses
phiPreHalf : out std_logic;
phiHalf : out std_logic;
phiPreEnd : out std_logic;
phiEnd : out std_logic;
-- First cycle where phiLocal is changed.
phiPost1 : out std_logic;
-- Second cycle after phiLocal change.
phiPost2 : out std_logic;
-- Third cycle after phiLocal change.
phiPost3 : out std_logic;
-- Forth cycle after phiLocal change.
phiPost4 : out std_logic
);
end entity;
chameleon/hwtest_readme.txt
The chameleon_* files are taken from the hwtest2 project for the Chameleon.
They are under the lgpl license, which I believe allows linking, such as it is in hardware...
---
Hi,
You are reading the readme of the chameleon_v5_hwtest package:
The project file and source-code for the Chameleon v5 (production) and docking-station hardware test.
It tests SDRAM, IR eye, PS/2 ports, buttons, VGA DACs, stereo audio output and IEC bus.
Also can be used to test Joystick ports, keyboard connector and Amiga LEDs control on the docking-station.
Instructions on use are in the toplevel VHDL file chameleon_v5_hwtest_top.vhd
For some of the tests extra hardware is required. Wiring instructions are included.
All code except for the hardware test itself can be used and redistributed
for your own (Turbo Chameleon 64) projects. Some of the files are LGPL licensed
and can be used in a wider range of projects. See comment section in each
individual file for the license and redistibution restrictions.
I wish you all much fun experimenting with the Chameleon!
Regards,
Peter Wendrich
pwsoft@syntiac.com
http://syntiac.com/chameleon.html
chameleon/lgpl.txt
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.
"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.
An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.
A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".
The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.
The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.
1. Exception to Section 3 of the GNU GPL.
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
2. Conveying Modified Versions.
If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:
a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:
a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license
document.
4. Combined Works.
You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:
a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.
1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff