--**************************************************************************/
--                                                                         */
--CC025953X - replacement for C025953 Atari 130XE chip using GAL6002       */
--                                                                         */
--PProvides 6 types of memory expansion for the 130XE                      */
--tthat can be done by replacing the 64k chips with 256k chips.            */
--TThe type of expansion can be selected by a hex coding switch.           */
--                                                                         */
--mmhalt is the latched halt signal. It is being latched with the falling  */
--eedge of phi2. That brings mhalt exactly into the bus cycle that ANTIC   */
--jjust asked for and now can be used to distiguish between CPU cycles     */
--aand ANTIC cycles.							   */
--									   */
--WWhenever the decoder finds that cas should go either to main memory or  */
--tto bank memory this information is latched with the rising edge of      */		
--pphi2. This shifts the time when cas is allowed to go through half a bus */
--ccycle forward allowing the original length cas signal to pass to        */
--eeither main or bank memory. 						   */
--NNot latching here works as well, however then casxxxx should only be    */
--aallowed when phi2 is high. This shortens the cas signals a bit.         */
--									   */
--TThe original C025953 lets the full length cas signal pass, so it 	   */ 
--aactually latches the cas pass through with the rising edge of phi2	   */
--                                                                         */
--GGAL22V10 works as well, but then you have to send the inverted phi2     */
--ssignal to pin 1 of 22V10 for the latching of halt. Use an 74LS04        */
--tto invert phi2 in this case.                                            */
--EEven 20V8 could work if you take out all modes but one.		   */			
--WWhen using one of these GALs you have to allow cas pass through only    */
--wwhen phi2 is high to prevent junk on the cas lines. (no latching here)  */
--                                                                         */
--SSwitch settings:                                                        */
--        0: 130XE compatible mode                                         */
--        1: 800XL compatible mode, 64 kb only                             */
--        2: "PB6" mode: PB2, PB3 & PB6 are used for bank select which     */
--           gives you 64kb regular base memory & 128kb extended bank      */
--           memory                                                        */
--        3: "German" type 256kb expansion. PB7, PB6, PB3 & PB2 are used   */
--           for bank select. This gives you 256kb extended bank memory.   */
--           If both PB4 & PB5 are 1 then PB7 still controls the self      */
--           test ROM.                                                     */
--        4: "American" type 256kb expansion. PB6, PB5, PB3 & PB2 are      */
--           used for bank select which gives you 256kb memory expansion.  */
--           However the independant access of Antic to the memory is lost.*/
--           PB4 controlls the access of both Antic and CPU to the memory  */
--        5: "448" mode. This gives you a total of 448kb memory expansion  */
--           it is in my eyes  the most logical use of the available       */
--           memory.                                                       */
--                                                                         */
--mmany thanks to http://www.s-direktnet.de/homepages/k_nadj/xebanks.html  */
--tthanks as well to http://cat.asw.cz/~kubecj/achemmu.htm                 */
--                                                                         */
--**************************************************************************/
--                                                                         */
--CCreated by:                                                             */
--CChristopher Lang, Dec. 2001, christopher.lang@plus.cablesurf.de         */
--                                                                         */
--**************************************************************************/



library ieee;
use ieee.std_logic_1164.all;

entity C025953X_Entity is
	port (phi2, cas, halt, cbe_pb4, vbe_pb5, ba14_pb2, ba15_pb3, pb6, pb7: in std_logic;
              a: in std_logic_vector (15 downto 14);
	      mode: in integer range 0 to 7;
              ra8, casmain, casbank, pb7_out: out std_logic;
    	      fa: out std_logic_vector (15 downto 14)
 	     );

attribute LOC: string;
attribute LOC of phi2: signal is "P1";
attribute LOC of a: signal is "P2;P19";
attribute LOC of ba14_pb2: signal is "P3";
attribute LOC of ba15_pb3: signal is "P4";
attribute LOC of cbe_pb4: signal is "P5";
attribute LOC of cas: signal is "P6";
attribute LOC of pb6: signal is "P7";

attribute LOC of mode: signal is "P10;P9;P8";

attribute LOC of halt: signal is "P11";

attribute LOC of casbank: signal is "P14";
attribute LOC of casmain: signal is "P15";
attribute LOC of vbe_pb5: signal is "P18";

attribute LOC of pb7: signal is "P20";
attribute LOC of ra8: signal is "P21";
attribute LOC of pb7_out: signal is "P22";


--iispDesignExpert 8.10 Copyright , 1992-2000, Lattice Semiconductor Corporation, All Rights Reserved

end;

--ssome stuff still from the Tango PLD version 
--ggroup bnksel_130[ba15_pb3, ba14_pb2];                    /* 64kb exp.  (130XE)
--ggroup bnksel_pb6[pb6, ba15_pb3, ba14_pb2];               /* 128kb exp. (PB6 only mode)
--ggroup bnksel_ger[pb7, pb6, ba15_pb3, ba14_pb2];          /* 256kb exp. ("German" or "Compy Shop" 320k)
--ggroup bnksel_usa[pb6, vbe_pb5, ba15_pb3, ba14_pb2];      /* 256kb exp. ("American 320k")
--ggroup bnksel_448[pb7, pb6, vbe_pb5, ba15_pb3, ba14_pb2]; /* 448kb exp. ("Chris's full 512k", 2 rows 256kbit chips



architecture C025953X_Architecture of C025953X_Entity is
signal mhalt: std_logic;

signal casmain_through: std_logic;	-- lets make this low active
signal casbank_through: std_logic;	-- lets make this low active

signal casmain_through_latched: std_logic;
signal casbank_through_latched: std_logic;

constant mode_130xe: integer := 7;
constant mode_800xl: integer := 6;
constant mode_pb6:   integer := 5;
constant mode_ger:   integer := 4;
constant mode_usa:   integer := 3;
constant mode_448:   integer := 2;

constant high: std_logic := '1';
constant low:  std_logic := '0';

constant bank_page: std_logic_vector := "01";



begin

latch_mhalt: process (phi2, halt) -- latch halt with falling edge of phi2        */
begin
	if falling_edge(phi2) then
		mhalt <= halt;
	end if;
end process latch_mhalt;



latch_cas_through_signals: process (phi2, casmain_through, casbank_through) -- latch through signals with rising edge
begin
	if rising_edge(phi2) then
		casmain_through_latched <= casmain_through;
		casbank_through_latched <= casbank_through;
	end if;
end process latch_cas_through_signals;



output_cas_signals: process (casmain_through_latched, casbank_through_latched, cas)
begin
	if casmain_through_latched = low then
		casmain <= cas;
	else
		casmain <= high;
	end if;

	if casbank_through_latched = low then
		casbank <= cas;
	else
		casbank <= high;
	end if;
end process output_cas_signals;



decode: process (phi2, cbe_pb4, vbe_pb5, ba14_pb2, ba15_pb3, pb6, pb7, a, mode, mhalt)
begin

  if a = bank_page then         -- access on $4000 to $7FFF occured
                                -- if ras = 1 ra8 = A16, while not active lower bit
                                -- if ras = 0 ra8 = A17, now ras went low, higher bit
    case mode is

--ggroup bnksel_130[ba15_pb3, ba14_pb2];         /* 64kb exp.  (130XE)     */
    when mode_130xe =>          -- mode 130xe ******************************/

        pb7_out <= pb7;

        if ( mhalt = high and cbe_pb4 = high )  -- CPU access on base ram **/
          or ( mhalt = low and vbe_pb5 = high ) then -- Antic access on base RAM
          ra8 <= low; fa <= a; -- casmain <= cas or not phi2; casbank <= high;
	  casmain_through <= low; casbank_through <= high;
        else                                     -- access on extended RAM */
          ra8 <= low;
          fa <= ba15_pb3 & ba14_pb2;
          -- casmain <= high; casbank <= cas or not phi2;
	  casmain_through <= high; casbank_through <= low;
  	end if;



--ggroup bnksel_800xl
    when mode_800xl =>          -- mode 800xl only 64kb ********************/

        pb7_out <= pb7;
        ra8 <= low; fa <= a; -- casmain <= cas or not phi2; casbank <= high;
	casmain_through <= low; casbank_through <= high;



--ggroup bnksel_pb6[pb6, ba15_pb3, ba14_pb2];   128kb exp. (PB6 only mode) */
    when mode_pb6 =>            -- 130xe mode plus pb6 for bank select *****/

        pb7_out <= pb7;

        if ( mhalt = high and cbe_pb4 = high ) -- CPU access on base ram ***/
          or ( mhalt = low and vbe_pb5 = high ) then -- Antic access on base RAM
          ra8 <= low; fa <= a; -- casmain <= cas or not phi2; casbank <= high;
  	  casmain_through <= low; casbank_through <= high;
        else                           -- access on extended RAM ***********/
          ra8 <= ( phi2 and low ) or ( not phi2 and pb6 );
          fa <= ba15_pb3 & ba14_pb2;
	  casmain_through <= high; casbank_through <= low;
          -- casmain <= high; casbank <= cas or not phi2;
	end if;



--ggroup bnksel_ger[pb7, pb6, ba15_pb3, ba14_pb2];          /* 256kb exp. ("German" or "Compy Shop" 320k)
    when mode_ger => -- German 130xe RAM expansion, pb2, pb3, pb6 pb7 = bank 
                     -- select, if pb4 and pb5 are both set to 1 then pb7    
                     -- controls self test                                   

        if (cbe_pb4 = high and vbe_pb5 = high) then
	    pb7_out <= pb7;
	else
	    pb7_out <= high;
	end if;


        if ( mhalt = high and cbe_pb4 = high ) -- CPU access on base ram ***/
          or ( mhalt = low and vbe_pb5 = high ) then -- Antic access on base RAM
          ra8 <= low; fa <= a; -- casmain <= cas or not phi2; casbank <= high;
  	  casmain_through <= low; casbank_through <= high;
        else                           -- access on extended RAM ***********/
          ra8 <= ( phi2 and pb7 ) or ( not phi2 and pb6 );
          fa <= ba15_pb3 & ba14_pb2;
	  casmain_through <= high; casbank_through <= low;
          -- casmain <= high; casbank <= cas or not phi2;
	end if;



--ggroup bnksel_usa[pb6, vbe_pb5, ba15_pb3, ba14_pb2];      /* 256kb exp. ("American 320k")
    when mode_usa => -- USA 130xe RAM expansion - pb2, pb3, pb5, pb6 = bank 
                     -- select, pb4 = access control for both CPU and Antic 

        pb7_out <= pb7;

        if cbe_pb4 = high then         -- CPU & Antic access on base ram ***/
          ra8 <= low; fa <= a; -- casmain <= cas or not phi2; casbank <= high;
  	  casmain_through <= low; casbank_through <= high;
        else                           -- access on extended RAM ***********/
          ra8 <= ( phi2 and pb6 ) or ( not phi2 and vbe_pb5 );
          fa <= ba15_pb3 & ba14_pb2;
	  casmain_through <= high; casbank_through <= low;
          -- casmain <= high; casbank <= cas or not phi2;
	end if;



--ggroup bnksel_448[pb7, pb6, vbe_pb5, ba15_pb3, ba14_pb2]; /* 448kb exp. ("Chris's full 512k", 2 rows 256kbit chips 
    when mode_448 => -- 448kb 130xe RAM expansion, pb2, pb3, pb5, pb6 pb7 = 
                   -- bank select, if pb4 is set to 1 then pb7             */
                   -- controls self test                                   */

        if cbe_pb4 = high then
	    pb7_out <= pb7;
        else
	    pb7_out <= high;
	end if;

        if cbe_pb4 = high then         -- CPU & Antic access on base ram ***/
          ra8 <= low; fa <= a; -- casmain <= cas or not phi2; casbank <= high;
  	  casmain_through <= low; casbank_through <= high;
        else                           -- access on extended RAM ***********/
          if std_logic_vector'(pb7 & pb6 & vbe_pb5 & ba15_pb3 & ba14_pb2) < "10000" then
                                       -- easy going here                  */
            ra8 <= (phi2 and pb6) or (not phi2 and vbe_pb5);
            fa <= ba15_pb3 & ba14_pb2;
    	    casmain_through <= high; casbank_through <= low;
            -- casmain <= high; casbank <= cas or not phi2;
          else
                                       -- access on upper 192k in 1st row  */
                                       -- not so easy, but doable          */
            if std_logic_vector'(pb7 & pb6 & vbe_pb5 & ba15_pb3 & ba14_pb2) < "11100" then
              if (pb6 = '0' and vbe_pb5 = '0') then
                ra8 <= (phi2 and '0') or (not phi2 and '1');
	      end if;	
              if (pb6 = '0' and vbe_pb5 = '1') then
                ra8 <= (phi2 and '1') or (not phi2 and '0');
	      end if;
              if (pb6 = '1' and vbe_pb5 = '0') then
                ra8 <= (phi2 and '1') or (not phi2 and '1');
	      end if;
              fa <= ba15_pb3 & ba14_pb2;
    	      casmain_through <= low; casbank_through <= high;
              -- casmain <= cas or not phi2;   -- cas goes to main bank, but only for the upper 192k
              -- casbank <= high;
            else                       -- floating bus returned            */
              ra8 <= high; fa <= ba15_pb3 & ba14_pb2;
    	      casmain_through <= high; casbank_through <= high;
	      -- casmain <= high;
              -- casbank <= high;
	    end if;
	  end if;
        end if;  


--ggroup bnksel_130[ba15_pb3, ba14_pb2];         /* 64kb exp.  (130XE)     */
    when others =>         -- mode 130xe ******************************/

        pb7_out <= pb7;

        if ( mhalt = high and cbe_pb4 = high )  -- CPU access on base ram **/
          or ( mhalt = low and vbe_pb5 = high ) then -- Antic access on base RAM
          ra8 <= low; fa <= a; -- casmain <= cas or not phi2; casbank <= high;
          casmain_through <= low; casbank_through <= high;
        else                                     -- access on extended RAM */
          ra8 <= low;
          fa <= ba15_pb3 & ba14_pb2;
          -- casmain <= high; casbank <= cas or not phi2;
          casmain_through <= high; casbank_through <= low;
  	end if;
    end case;



  else
    ra8 <= low; fa <= a; -- casmain <= cas or not phi2; casbank <= high;
    casmain_through <= low; casbank_through <= high;
    pb7_out <= pb7;
  end if;
end process decode;



--CCopyright (c) 1994-2000 Synplicity, Inc.  All rights reserved.	

end C025953X_Architecture;



