Amiga 600 con Gayle ver.1, implementazione VHDL del PAL di supporto
Questo articolo è specifico per l'Amiga 600, per cui le denominazioni dei chip, gli indirizzamenti e tutto il resto sono relativi a questo sistema, anche quando non espressamente indicato.
Gayle è il chip custom preposto, tra molte altre cose, al controllo della porta ATA (IDE). Esistono due versioni identificate dai seguenti chip numbers:
Versione 1: 391155-01
Versione 2: 391155-02
Per quanto sono riuscito a capire, l'unica differenza tra le due è il mancato (incompleto? erroneo?) supporto alla porta ATA nella prima versione: in pratica la versione 391155-01 ha bisogno di una logica esterna per generare i segnali IDE_CS1 e IDE_CS2, necessari per controllare un hard disk IDE.
Inoltre, la logica esterna, controlla i segnali RTC_CS (selezione clock port 1), SPARE_CS (selezione clock port 2) e NET_CS (selezione chip arcnet). Ovviamente anche questi vengono controllati direttamente nella seconda versione di Gayle.
Nell'Amiga questa logica è implementata dal chip XU1, un PAL16L8B, cioè una logica programmabile non riscrivibile.
Questa è la parte dello schema che mostra come Gayle è collegato al PAL:
Ovviamente XU1 (il PAL) è montato solo nelle motherboard dove c'è la prima versione di Gayle, dove i jumpers XJ1E, XJ1D, XJ1C, XJ1B e XJ1A sono aperti (cioè non è Gayle a controllare questi segnali). Nell'Amiga che ho utilizzato per i test sono state tagliate le tracce del circuito stampato (in realtà l'ho già trovato così ed il problema iniziale era proprio quello di aggiungere un HDD, ma non c'era il PAL168B...):
Il PAL funziona solamente da address decoding in quanto gli unici input solo le linee di indirizzo da A12 a A23.
Di seguito descriverò una possibile implementazione su GAL16V8 scritta in VHDL. L'unico test che ho potuto fare è il funzionamento di un hard disk IDE (segnali IDE_CS1 e IDE_CS2), per cui almeno la parte che controlla questi segnali è corretta.
IDE_CS1 è connesso a CS1FX (Host Chip Select 0) del connettore IDE, mentre IDE_CS2 è connesso a CS3FX (Host Chip Select 1). Questi segnali servono a selezionare il blocco di registri richiesto (command block o control block) del dispositivo IDE. Alcuni siti riportano erroneamente che questi segnali selezionano il drive attivo.
Su amigawiki.org ho trovato le specifiche di Gayle (https://www.amigawiki.org/lib/exe/fetch.php?media=de:parts:gayle_specification.pdf) dove si trova una tabella che associa il range di indirizzi ai segnali CS1 e CS2:
Quindi il range di indirizzi dedicati all'IDE è nei 32K che spaziano tra 0xDA0000 e 0xDA7FFF, tuttavia, dalle memory map si vede che il limite massimo può essere esteso fino a 0xDAFFFF, per cui in VHDL la decodifica potrebbe essere implementata così:
process (A)
begin
if A(23 downto 16) = x"DA" and A(14) = '0' then
IDE_CS1 <= A(12);
IDE_CS2 <= not A(12);
else
IDE_CS1 <= '1';
IDE_CS2 <= '1';
end if;
end process;
Sempre secondo le memory map che si trovano in rete, SPARE_CS viene attivato nel range 0xD80000-0xD8FFFF, mentre RTC_CS nel range 0xDC0000-0xDCFFFF ed infine NET_CS nel range 0xD90000-0xD9FFFF:
SPARE_CS <= '0' when A(23 downto 16) = x"D8" else '1';
RTC_CS <= '0' when A(23 downto 16) = x"DC" else '1';
NET_CS <= '0' when A(23 downto 16) = x"D9" else '1';
Di seguito c'è il codice VHDL completo per la programmazione del GAL16V8. Per compilarlo e generare il file Jedec occorre "Lattice ispLEVER Classic", scaricabile gratuitamente da qui:
Il file compilato Jedec (per esempio "addr_decoder.jed") può essere programmato nel GAL con un programmatore generico, tipo il TL866.
-- 2018 by Fabrizio Di Vittorio (fdivitto2013@gmail.com)
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity addr_decoder is
port (A: in std_logic_vector (23 downto 12);
IDE_CS1: out std_logic;
IDE_CS2: out std_logic;
RTC_CS: out std_logic;
NET_CS: out std_logic;
SPARE_CS: out std_logic);
attribute LOC: string;
attribute LOC of A: signal is "P1 P2 P3 P4 P5 P6 P7 P8 P9 P11 P13 P14";
attribute LOC of IDE_CS1: signal is "P16";
attribute LOC of IDE_CS2: signal is "P15";
attribute LOC of RTC_CS: signal is "P18";
attribute LOC of NET_CS: signal is "P17";
attribute LOC of SPARE_CS: signal is "P19";
end addr_decoder;
architecture Behavioral of addr_decoder is
begin
-- IDE_CS1 and IDE_CS2 (IDE HARD DRIVE) selection schema:
-- A14 A13 A12 Address Range Signal Selected (LOW)
-- 0 0 0 0xDA0000-0xDA0FFF CS1
-- 0 0 1 0xDA1000-0xDA1FFF CS2
-- 0 1 0 0xDA2000-0xDA2FFF CS1
-- 0 1 1 0xDA3000-0xDA3FFF CS2
-- 1 0 0 0xDA4000-0xDA4FFF None
-- 1 0 1 0xDA5000-0xDA5FFF None
-- 1 1 0 0xDA6000-0xDA6FFF None
-- 1 1 1 0xDA7000-0xDA7FFF None
process (A)
begin
if A(23 downto 16) = x"DA" and A(14) = '0' then
IDE_CS1 <= A(12);
IDE_CS2 <= not A(12);
else
IDE_CS1 <= '1';
IDE_CS2 <= '1';
end if;
end process;
-- SPARE_CS (Real Time Clock) selected (LOW) for address in 0xD80000-0xD8FFFF
SPARE_CS <= '0' when A(23 downto 16) = x"D8" else '1';
-- RTC_CS (Real Time Clock) selected (LOW) for addresses in 0xDC0000-0xDCFFFF
RTC_CS <= '0' when A(23 downto 16) = x"DC" else '1';
-- NET_CS (arcnet chip select) selected (LOW) for addresses in 0xD90000-0xD9FFFF
NET_CS <= '0' when A(23 downto 16) = x"D9" else '1';
end Behavioral;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity addr_decoder is
port (A: in std_logic_vector (23 downto 12);
IDE_CS1: out std_logic;
IDE_CS2: out std_logic;
RTC_CS: out std_logic;
NET_CS: out std_logic;
SPARE_CS: out std_logic);
attribute LOC: string;
attribute LOC of A: signal is "P1 P2 P3 P4 P5 P6 P7 P8 P9 P11 P13 P14";
attribute LOC of IDE_CS1: signal is "P16";
attribute LOC of IDE_CS2: signal is "P15";
attribute LOC of RTC_CS: signal is "P18";
attribute LOC of NET_CS: signal is "P17";
attribute LOC of SPARE_CS: signal is "P19";
end addr_decoder;
architecture Behavioral of addr_decoder is
begin
-- IDE_CS1 and IDE_CS2 (IDE HARD DRIVE) selection schema:
-- A14 A13 A12 Address Range Signal Selected (LOW)
-- 0 0 0 0xDA0000-0xDA0FFF CS1
-- 0 0 1 0xDA1000-0xDA1FFF CS2
-- 0 1 0 0xDA2000-0xDA2FFF CS1
-- 0 1 1 0xDA3000-0xDA3FFF CS2
-- 1 0 0 0xDA4000-0xDA4FFF None
-- 1 0 1 0xDA5000-0xDA5FFF None
-- 1 1 0 0xDA6000-0xDA6FFF None
-- 1 1 1 0xDA7000-0xDA7FFF None
process (A)
begin
if A(23 downto 16) = x"DA" and A(14) = '0' then
IDE_CS1 <= A(12);
IDE_CS2 <= not A(12);
else
IDE_CS1 <= '1';
IDE_CS2 <= '1';
end if;
end process;
-- SPARE_CS (Real Time Clock) selected (LOW) for address in 0xD80000-0xD8FFFF
SPARE_CS <= '0' when A(23 downto 16) = x"D8" else '1';
-- RTC_CS (Real Time Clock) selected (LOW) for addresses in 0xDC0000-0xDCFFFF
RTC_CS <= '0' when A(23 downto 16) = x"DC" else '1';
-- NET_CS (arcnet chip select) selected (LOW) for addresses in 0xD90000-0xD9FFFF
NET_CS <= '0' when A(23 downto 16) = x"D9" else '1';
end Behavioral;
Il sorgente VHDL ed il file Jedec compilato si trovano sul mio profilo github:
https://github.com/fdivitto/Amiga600GALFirmware
https://github.com/fdivitto/Amiga600GALFirmware
Commenti
Posta un commento