Amiga 600 with Gayle ver.1, VHDL code to implement PAL chip (XU1)
This article is specific to the Amiga 600, so the chip designations, addressing and all the rest are related to this system, even when not explicitly indicated.
Gayle is the custom chip that, among many other things, controls the ATA (IDE) port. There are two versions identified by the following chip numbers:
Version 1: 391155-01
Version 2: 391155-02
As far as I could understand, the only difference between the two is the lack (incomplete? Erroneous?) of support for the ATA port in the first version: in detail, version 391155-01 needs an external logic to generate the IDE_CS1 and IDE_CS2 signals, which are needed to control an IDE hard disk.
In addition, the external logic controls the RTC_CS (Clock Port 1 selection), SPARE_CS (Clock Port 2 selection) and NET_CS (Arcnet chip selection) signals. Obviously these are also directly handled in the second version of Gayle.
In the Amiga this logic is implemented by the XU1 chip, a PAL16L8B, which is a programmable logic that can not be rewritten.
This is the part of the scheme that shows how Gayle is connected to the PAL:
XU1 (the PAL) is mounted on motherboards where there is the first version of Gayle, where XJ1E, XJ1D, XJ1C, XJ1B and XJ1A jumpers are left open (that is Gayle doesn't handle these signals). In the Amiga I used for the tests the traces have been brutally cut (in fact it was already like that and the goal was just to add an HDD, but there was not the PAL168B chip inside...):
PAL just works as address decoder because the only inputs are the address lines from A12 to A23.
Below I will describe a possible implementation using GAL16V8 and written in VHDL. Unfortunately I could only test that the IDE hard disk actually works (signals IDE_CS1 and IDE_CS2), because I haven't an RTC or Arcnet.
IDE_CS1 is connected to CS1FX (Host Chip Select 0) and IDE_CS2 is connected to CS3FX (Host Chip Select 1) of the IDE connector. These signals are used to select the required register block (Command Block or Control Block) of the IDE device. Some sites erroneously report that these signals select the active drive.
On amigawiki.org there is a draft of Gayle specifications where there is a table that associates the address range to the signals CS1 and CS2:
So the address range dedicated to the IDE is in the 32K block ranging between 0xDA0000 and 0xDA7FFF. However, Amiga memory map tells us that the maximum limit can be extended up to 0xDAFFFF, so in VHDL, the decoding could be implemented like this:
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;
Also, according to the memory map, SPARE_CS is activated in the range 0xD80000-0xD8FFFF, while RTC_CS in the range 0xDC0000-0xDCFFFF and finally NET_CS in the 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';
Below there is the complete VHDL code to program the GAL16V8. To compile it and generate the Jedec file you need "Lattice ispLEVER Classic", which can be freely downloaded from here:
Finally, the Jedec compiled file (ie "addr_decoder.jed") can be programmed using a generic programmer like the cheap 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;
VHDL source and compiled Jedec file can be downloaded from my github profile:
https://github.com/fdivitto/Amiga600GALFirmware
https://github.com/fdivitto/Amiga600GALFirmware
Commenti
Posta un commento