| | Start | | http://hardware.atari8.info |
|
Prawdziwe oblicze Freddie'ego Freddie jest "skromnym" układem. Dlaczego? Nie chodzi tutaj o jego wielkość - wszak ma przecież 40 nóg. Chodzi o to, że w prosty sposób nie można zauważyć jego dość ciężkiej i monotonnej pracy w Atari. O innych układach, takich jak Antic, GTIA czy Pokey, napisano już wiele, a o Freddie'im oprócz tego, że steruje pamięcią - nic. Przyczyna prawdopodobnie tkwi w tym, że z punktu widzenia użytkownika Freddie'im nie można sterować, nie ma żadnych rejestrów, do których można by coś wpisać, czy coś z nich odczytać. Poznanie jednak jego działania jest ważne dla poznania zasady pracy całego Atari, bo to przecież dzięki niemu procesor ma do dyspozycji prawie 64kB RAM-u. Freddie został wprowadzony wraz z serią 1400XL/1450XLD jako unowocześnienie elektroniki komputera Atari. Dzięki niemu na płycie zaoszczędzono nieco miejsca (zastępuje on kilka scalaków, w tym linię opóźniającą) i zmniejszono koszty produkcji. Po "wycofaniu" serii 1400XL/1450XLD Freddie'ego montowano w końcowych egzemplarzach Atari 800XL (zwanych 800XLF) oraz w nowej serii XE. Jest zatem najmłodszy (jego numer seryjny to CO61922 lub CO61991), jak i najprostszy pod względem konstrukcji ze wszystkich układów VLSI montowanych w Atari. Jak on zatem działa? Na rysunku 1 pokazana jest jego topografia. ![]() Rys.1 Freddie
Oto jego sygnały: W Internecie dostępny jest schemat wewnętrznej struktury Freddie'ego. Według niego Freddie zawiera w swoim wnętrzu kilka scalaków ze zwykłej rodziny TTL oraz CMOS, a sygnały RAS i CAS są generowane poprzez zwykłe opóźnianie sygnału o2. Nic w tym złego, bo przecież w 800XL tak właśnie jest robione. Mimo wszystko powstał układ testujący, dzięki któremu w sposób statyczny można było sprawdzić, co we Freddie'im naprawdę siedzi. Schemat układu pokazuje rysunek 2. ![]() Rys.2 Schemat układu testowego Freddiego Układ 74LS74 zastosowano w celu zabezpieczenia sygnału taktującego przed drganiami styków przełącznika. Zestaw jumperków oraz przełączników umożliwia zbadanie wpływu wejść R/W, o2, CasInh, ExtSel i RESET na wyjścia. Dodatkowo możliwe jest - poprzez zmianę stanów na liniach A0 i A8 - zbadanie wewnętrznego sygnału multipleksującego (MPY) sygnały adresowe. W ten sposób otrzymano tabelę stanów, na podstawie której możliwe było rozrysowanie przebiegów pokazanych na rysunku 3. ![]() Rys.3 Przebiegi w układzie Freddiego Jak widać, wnętrze Freddie'ego to czysty synchroniczny układ, w którym nie ma celowego opóźniania (poprzez zestaw bramek) sygnałów RAS i CAS. Na podstawie częstotliwości sygnału zegara można wyliczyć zależności między niektórymi sygnałami. Pokazuje to tabela 1.
Dodatkowo, czego na rysunku 3 dobrze nie widać, sygnał W przybiera stan sygnału RW od drugiego narastającego zbocza sygnału zegarowego i dodatkowo jest zatrzaskiwany wraz z opadającym zboczem sygnału RAS. Ciekawostką jest właśnie zmiana stanów sygnałów RAS i CAS w chwilach opadającego zbocza sygnału taktującego. W większości układach synchronicznych zmiana stanów następuje bowiem po narastającym zboczu. Mając zależności czasowe można pokusić się o coś więcej, czyli zaprojektowanie wnętrza Freddie'ego w popularnym języku VHDL i jego późniejszej symulacji lub nawet implementacji w jakiejś programowalnej kości FPGA czy CPLD. Poniższy listing jest jedną z możliwości zapisania funkcji Freddie'ego tak, by przebiegi wyjściowe zgadzały się z rzeczywistością.
ibrary IEEE;
use IEEE.std_logic_1164.all;
entity freddie is
port (
clk_in :in std_logic;
clk_out :out std_logic;
rst :in std_logic;
extsel :in std_logic;
casinh :in std_logic;
phi2 :in std_logic;
rw :in std_logic;
a :in std_logic_vector(15 downto 0);
osc :out std_logic;
ras :out std_logic;
cas :out std_logic;
w :out std_logic;
ba :out std_logic_vector(7 downto 0)
);
end freddie;
architecture a_freddie of freddie is
signal neg_clk :std_logic;
signal fcount :std_logic_vector(2 downto 0);
signal mpy :std_logic;
signal l_rw :std_logic;
begin
freddie_counter: process(clk_in,rst)
begin
if rst='0' then
fcount <= "000";
elsif clk_in'event and clk_in='1' then
fcount(0) <= (not fcount(2) and not fcount(1) and not phi2)
or (fcount(2) and fcount(1) and phi2);
fcount(1) <= (not fcount(2) and fcount(0) and not phi2)
or (not fcount(2) and fcount(1) and not fcount(0) and not phi2)
or (fcount(2) and fcount(1) and not fcount(0) and phi2);
fcount(2) <= (not fcount(2) and fcount(1) and not fcount(0) and not phi2)
or (fcount(2) and fcount(1) and not fcount(0) and phi2)
or (fcount(2) and fcount(0) and phi2);
end if;
end process freddie_counter;
ras_rw: process(neg_clk,rst)
begin
if rst='0' then
ras <= '1';
l_rw <= '1';
elsif neg_clk'event and neg_clk='1' then
if fcount="000" or fcount="001" or fcount="011" then
ras <= '1';
else
ras <= '0';
end if;
if fcount="010" then
l_rw <= rw;
end if;
end if;
end process ras_rw;
neg_clk <= not clk_in;
clk_out <= neg_clk;
osc <= '1' when fcount(2 downto 1)="00" or fcount(2 downto 1)="11" else '0';
mpy <= '0' when fcount="001" or fcount="011" or fcount="010" else '1';
ba(0) <= a(0) when mpy='0' else a(8);
ba(1) <= a(1) when mpy='0' else a(9);
ba(2) <= a(2) when mpy='0' else a(10);
ba(3) <= a(3) when mpy='0' else a(11);
ba(4) <= a(4) when mpy='0' else a(12);
ba(5) <= a(5) when mpy='0' else a(13);
ba(6) <= a(6) when mpy='0' else a(14);
ba(7) <= a(7) when mpy='0' else a(15);
w <= rw when fcount="001" or fcount="011" or (fcount="010" and neg_clk='0') else l_rw;
cas <= '1' when extsel='0' or casinh='0'
or fcount="011" or fcount="010" or fcount="110"
or (l_rw='1' and fcount="001")
or (l_rw='0' and fcount="111")
or (l_rw='0' and fcount="001" and neg_clk='1')
or (l_rw='0' and fcount="101" and neg_clk='0')
else '0';
end a_freddie;
Źródła kodu wraz z testbenchem oczywiście są dostępne: freddie.vhd, tb_freddie.vhd. Wynik symulacji można zobaczyć tu. Pasiu/SSG |
|
|
|