home *** CD-ROM | disk | FTP | other *** search
- -- csg reu/rec COMPATIBLE ram EXPANSION CONTROLLER
- -- INITIAL VERSION: 2.9.2001 BY rAINER bUCHTY (RAINER@BUCHTY.NET)
- --
- -- 16mb dram TO 64Kb c64 MEMORY dma UNIT
-
- LIBRARY ieee;
- USE ieee.STD_LOGIC_1164.ALL;
- USE ieee.STD_LOGIC_ARITH.ALL;
- USE ieee.STD_LOGIC_UNSIGNED.ALL;
-
- COMPONENT REC IS
- PORT(
- PHI2, DOTCLK:IN STD_LOGIC;
- RST:IN STD_LOGIC;
-
- DMA:OUT STD_LOGIC;
- BA:IN STD_LOGIC;
-
- CPU_ADDR:INOUT STD_LOGIC_VECTOR(15 DOWNTO 0);
- CPU_DATA:INOUT STD_LOGIC_VECTOR(7 DOWNTO 0);
- CPU_RW:INOUT STD_LOGIC;
-
- REU_ADDR:OUT STD_LOGIC_VECTOR(11 DOWNTO 0);
- REU_DATA:INOUT STD_LOGIC_VECTOR(7 DOWNTO 0);
- REU_RW:OUT STD_LOGIC;
- REU_RAS,
- REU_CAS:OUT STD_LOGIC;
-
- SIZE:IN STD_LOGIC;
-
- AEC:INOUT STD_LOGIC;
- BA:INOUT STD_LOGIC
- );
- END COMPONENT;
-
- -- --------------------------------------------------------------------------
-
- LIBRARY ieee;
- USE ieee.STD_LOGIC_1164.ALL;
- USE ieee.STD_LOGIC_ARITH.ALL;
- USE ieee.STD_LOGIC_UNSIGNED.ALL;
-
- ENTITY REC IS
- PORT(
- PHI2, DOTCLK:IN STD_LOGIC;
- RST:IN STD_LOGIC;
-
- DMA:OUT STD_LOGIC;
- BA:IN STD_LOGIC;
-
- CPU_ADDR:INOUT STD_LOGIC_VECTOR(15 DOWNTO 0);
- CPU_DATA:INOUT STD_LOGIC_VECTOR(7 DOWNTO 0);
- CPU_RW:INOUT STD_LOGIC;
-
- REU_ADDR:OUT STD_LOGIC_VECTOR(11 DOWNTO 0);
- REU_DATA:INOUT STD_LOGIC_VECTOR(7 DOWNTO 0);
- REU_RW:OUT STD_LOGIC;
- REU_RAS,
- REU_CAS:OUT STD_LOGIC;
-
- SIZE:IN STD_LOGIC;
-
- AEC:INOUT STD_LOGIC;
- BA:INOUT STD_LOGIC
- );
- END ENTITY;
-
- -- --------------------------------------------------------------------------
-
- ARCHITECTURE ARCH_REC OF REC IS
-
- -- acr AND imr
- SIGNAL ACR: STD_LOGIC_VECTOR(1 DOWNTO 0);
- SIGNAL IMR: STD_LOGIC_VECTOR(2 DOWNTO 0);
-
- -- cr
- SIGNAL EXECUTE, LOAD, FF00:STD_LOGIC;
- SIGNAL TT:STD_LOGIC_VECTOR(1 DOWNTO 0);
-
- -- sr
- SIGNAL IP, EOB, FAULT: STD_LOGIC_VECTOR;
- CONSTANT VERSION: STD_LOGIC_VECTOR(3 DOWNTO 0):="0000";
-
- -- MAIN STATE MACHINE
- SIGNAL STATE: STD_LOGIC_VECTOR(3 DOWNTO 0);
-
- -- TRANSFER CONTROL
- SIGNAL BASE_REU, SADR_REU: STD_LOGIC_VECTOR(23 DOWNTO 0);
- SIGNAL BASE_C64, SADR_C64: STD_LOGIC_VECTOR(15 DOWNTO 0);
- SIGNAL XFER_CNT, XFER_LEN: STD_LOGIC_VECTOR(15 DOWNTO 0);
-
- -- swap STORAGE
- SIGNAL REU_STORE, CPU_STORE:STD_LOGIC_VECTOR(7 DOWNTO 0);
-
- -- MISC
- SIGNAL REF_CNT:STD_LOGIC_VECTOR(11 DOWNTO 0);-- REFRESH COUNTER
- SIGNAL EXEC_S:STD_LOGIC;-- EXEC SAMPLED
- SIGNAL BA_S:STD_LOGIC;-- BA SAMPLED
- SIGNAL SCNT:STD_LOGIC;-- swap STATE
-
- BEGIN
-
- -- --------------------------------------------------------------------------
- -- dma TRANSFER
- -- --------------------------------------------------------------------------
- PROCESS(DOTCLK,RST)
- BEGIN
- IF RST='0' THEN
- BASE_REU<="000000000000000000000000";
- BASE_C64<="0000000000000000";
- XFER_CNT<="0000000000000000";
-
- REF_CNT<="000000000000";
-
- REU_RAS<='1';
- REU_CAS<='1';
- REU_RW<='1';
- CPU_RW<='z';
-
- EXEC_S<='0';
- BA_S<=BA;
-
- STATE<="000";
- SCNT<='0';
-
- -- RISING EDGE: ram ADDRESSING & DATA TRANSFER
- ELSIF RISING'EDGE(DOTCLK) THEN
- BA_S<=BA;
-
- -- MUTE C64 LINES BY DEFAULT
- CPU_ADDR<="zzzzzzzzzzzzzzzz";
- CPU_DATA<="zzzzzzzz";
- CPU_RW<='z';
-
- -- TRANSFER CONTROL REGISTERS WHILE IDLE
- IF EXEC_S='0' THEN
- BASE_REU<=SADR_REU;
- BASE_C64<=SADR_C64;
- XFER_CNT<=XFER_LEN;
-
- EXEC_S<=EXECUTE;
- SCNT<='0';
-
- -- MEMORY ACCESS
- ELSE IF BA='1' THEN
- CASE STATE IS
- WHEN "000" =>-- APPLY ROW ADDR
- REU_ADDR<=BASE_REU(11 DOWNTO 0);
- CPU_ADDR<=BASE_C64;
-
- WHEN "001" =>-- APPLY COL ADDR
- REU_ADDR<=BASE_REU(23 DOWNTO 12);
- CPU_ADDR<=BASE_C64;
-
- WHEN "010" =>-- TRANSFER DATA
- CPU_ADDR<=BASE_C64;
-
- FAULT<='0';
-
- CASE TT IS
- WHEN "00" =>-- c64->reu
- REU_DATA<=CPU_DATA;
-
- WHEN "01" =>-- reu->c64
- CPU_DATA<=REU_DATA;
-
- WHEN "10" =>-- swap
- IF SCNT='0' THEN
- REU_STORE<=CPU_DATA;
- CPU_STORE<=REU_DATA;
- ELSE
- REU_DATA<=REU_STORE;
- CPU_DATA<=CPU_STORE;
- END IF;
-
- SCNT<=NOT(SCNT);
-
- WHEN "11" =>-- verify
- IF CPU_DATA/=REU_DATA
- FAULT<='1';
- END IF;
-
- WHEN OTHERS =>
- NULL;
-
- END CASE;
-
- WHEN "011" =>-- INC ADDRESSES, DEC COUNTER
- XFER_CNT<=XFER_CNT-1;
-
- IF ACR(0)='1' THEN
- BASE_REU<=BASE_REU+1;
- END IF;
-
- IF ACR(0)='1' THEN
- BASE_C64<=BASE_C64+1;
- END IF;
-
-
- WHEN "100" =>-- cbr #1
- REU_ADDR<=REF_CNT;
-
- WHEN "101" =>-- cbr #2
- REU_ADDR<="000000000000";
-
- WHEN "111" =>-- FINISH/RELOAD
- REF_CNT<=REF_CNT+1;
-
- IF XFER_CNT=0 THEN
- IF RELOAD='1' THEN
- BASE_REU<=SADR_REU;
- BASE_C64<=SADR_C64;
- XFER_CNT<=XFER_LEN;
- END IF;
-
- EOB<='1';
- EXEC_S<='0';
- END IF;
-
- WHEN OTHERS =>
- NULL;
-
- END CASE;
- END IF;
-
- -- FALLING EDGE: ram CONTROL
- ELSIF FALLING'EDGE(DOTCLK) THEN
- -- ram CONTROL DEFAULTS
- CPU_RW<='1';
- REU_RW<='1';
- REU_RAS<='1';
- REU_CAS<='1';
-
- IF EXEC_S='1' AND BA_S<='1' THEN
- STATE<=STATE+1;
-
- -- ram CONTROL STATE MACHINE
- CASE STATE IS
- WHEN "000" =>-- SAMPLE ROW ADDR
- REU_RAS<='0';
- REU_CAS<='1';
-
- WHEN "001" =>-- SAMPLE COL ADDR
- REU_RAS<='0';
- REU_CAS<='0';
-
- WHEN "010" =>-- DATA WRITE
- REU_RAS<='0';
- REU_CAS<='0';
-
- CASE TT IS
- WHEN "00" =>-- c64->reu
- REU_RW<='0';
- WHEN "01" =>-- reu->c64
- CPU_RW<='0';
- WHEN "10" =>-- swap
- IF SCNT='1' THEN
- CPU_RW<='0';
- REU_RW<='0';
- END IF;
- WHEN OTHERS =>
- NULL;
-
- END CASE;
-
- WHEN "011" =>-- END OF TRANSFER
- REU_RAS<='1';
- REU_CAS<='0';
-
- WHEN "100" => -- cbr #1
- REU_RAS<='1';
- REU_CAS<='0';
-
- WHEN "101" =>-- cbr #2
- REU_RAS<='0';
- REU_CAS<='0';
-
- WHEN OTHERS =>
- REU_RAS<='1';
- REU_CAS<='1';
-
- END CAS-E;
- END IF;
- END IF;
- END PROCESS;
-
-
- -- --------------------------------------------------------------------------
- -- EXTERNAL ACCESS TO reu REGISTERS
- -- --------------------------------------------------------------------------
- REG_ACCESS:
- PROCESS(PHI2,RST)
- BEGIN
- VARIABLE REG_ADDR: STD_LOGIC_VECTOR(3 DOWNTO 0);
-
- IF RST='0' THEN
- EXECUTE<='0';
- LOAD<='0';
- FF00<='0';
-
- SADR_C64<="0000000000000000";
- SADR_REU<="000000000000000000000000";
- XFER_LEN<="0000000000000000";
-
- IMR<="000";
- ACR<="00";
-
- ELSIF (PHI2'EVENT AND PHI2='1') THEN
- REG_ADDR:=CPU_ADR(3 DOWNTO 0);
-
- -- CLEAR EXECUTE WHEN FINISHED
- IF EXEC_S='1' AND EXECUTE='1' THEN
- EXECUTE<='0';
-
- -- AUTO-EXECUTE ON FF00 ACCESS
- ELSIF LOAD='1' AND CPU_ADR="1111111100000000" THEN
- EXECUTE<='1';
-
- -- NORMAL ACCESS
- ELSIF CPU_RW='0' THEN
-
- CASE REG_ADDR IS
-
- WHEN "0001" =>-- cr
- EXECUTE<=CPU_DBUS(7);
- LOAD<=CPU_DBUS(5);
- FF00<=CPU_DBUS(4);
- TT<=CPU_DBUS(1 DOWNTO 0);
-
- WHEN "0010" =>-- C64 START ADDRESS
- SADR_C64(15 DOWNTO 8)<=CPU_DBUS;
- WHEN "0011" =>
- SADR_C64( 7 DOWNTO 0)<=CPU_DBUS;
-
- WHEN "0100" =>-- REU START ADDRESS
- SADR_REU(23 DOWNTO 16)<=CPU_DBUS;
- WHEN "0101" =>
- SADR_REU(16 DOWNTO 8)<=CPU_DBUS;
- WHEN "0110" =>
- SADR_REU( 7 DOWNTO 0)<=CPU_DBUS;
-
- WHEN "0111" =>-- TRANSFER LENGTH
- XFER_LEN(15 DOWNTO 8)<=CPU_DBUS;
- WHEN "1000" =>
- XFER_LEN( 7 DOWNTO 0)<=CPU_DBUS;
-
- WHEN "1001" =>-- imr
- IMR<=CPU_DBUS(7 DOWNTO 5);
-
- WHEN "1010" =>-- acr
- ACR<=CPU_DBUS(7 DOWNTO 6);
-
- WHEN OTHERS =>
- NULL;
-
- END CASE;
-
- ELSIF CPU_RW='1' THEN
- CASE REG_ADDR IS
- WHEN "0000" =>-- sr
- CPU_DBUS<=IP & EOB & FAULT & SIZE & VERSION;
-
- WHEN "0001" =>-- cr
- CPU_DBUS<=EXECUTE & '1' & LOAD & FF00 & "11" & TT;
-
- WHEN "0010" =>-- C64 START ADDRESS
- CPU_DBUS<=SADR_C64(15 DOWNTO 8);
- WHEN "0011" =>
- CPU_DBUS<=SADR_C64( 7 DOWNTO 0);
-
- WHEN "0100" =>-- REU START ADDRESS
- CPU_DBUS<=SADR_REU(23 DOWNTO 16);
- WHEN "0101" =>
- CPU_DBUS<=SADR_REU(15 DOWNTO 8);
- WHEN "0110" =>
- CPU_DBUS<=SADR_REU( 7 DOWNTO 0);
-
- WHEN "0111" =>-- TRANSFER LENGTH
- CPU_DBUS<=XFER_LEN(15 DOWNTO 8);
- WHEN "1000" =>
- CPU_DBUS<=XFER_LEN( 7 DOWNTO 0);
-
- WHEN "1001" =>-- imr
- CPU_DBUS<=IMR & "11111";
-
- WHEN "1010" =>-- acr
- CPU_DBUS<=ACR & "111111";
-
- WHEN OTHERS =>
- NULL;
-
- END CASE;
- END IF;
- END IF;
- END PROCESS;
-
-
- END ARCHITECTURE;