OpenCores
URL https://opencores.org/ocsvn/z80soc/z80soc/trunk

Subversion Repositories z80soc

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /z80soc/tags/z80soc05b/rtl
    from Rev 8 to Rev 31
    Reverse comparison

Rev 8 → Rev 31

/VHDL/PS2/ps2bkd.vhd.bak
0,0 → 1,143
library IEEE;
use IEEE.std_logic_1164.all;
 
entity ps2kbd is
PORT (
keyboard_clk : inout std_logic;
keyboard_data : inout std_logic;
clock : in std_logic;
reset : in std_logic;
read : in std_logic;
scan_ready : out std_logic;
ps2_ascii_code : out std_logic_vector(7 downto 0));
end ps2kbd;
architecture rtl of ps2kbd is
 
signal scan_code_sig : std_logic_vector(7 downto 0);
signal scode_shf_sig : std_logic_vector(11 downto 0);
 
begin
 
scode_shf_sig <= "0000" & scan_code_sig;
 
ps2_ascii_decode : process(scode_shf_sig)
begin
case scode_shf_sig is
when x"066" => ps2_ascii_code <= x"08"; -- Backspace ("backspace" key)
when x"00d" => ps2_ascii_code <= x"09"; -- Horizontal Tab
when x"05a" => ps2_ascii_code <= x"0d"; -- Carriage return ("enter" key)
when x"076" => ps2_ascii_code <= x"1b"; -- Escape ("esc" key)
when x"029" => ps2_ascii_code <= x"20"; -- Space
when x"116" => ps2_ascii_code <= x"21"; -- !
when x"152" => ps2_ascii_code <= x"22"; -- "
when x"126" => ps2_ascii_code <= x"23"; -- #
when x"125" => ps2_ascii_code <= x"24"; -- $
when x"12e" => ps2_ascii_code <= x"25"; --
when x"13d" => ps2_ascii_code <= x"26"; --
when x"052" => ps2_ascii_code <= x"27"; --
when x"146" => ps2_ascii_code <= x"28"; --
when x"145" => ps2_ascii_code <= x"29"; --
when x"13e" => ps2_ascii_code <= x"2a"; -- *
when x"155" => ps2_ascii_code <= x"2b"; -- +
when x"041" => ps2_ascii_code <= x"2c"; -- ,
when x"04e" => ps2_ascii_code <= x"2d"; -- -
when x"049" => ps2_ascii_code <= x"2e"; -- .
when x"04a" => ps2_ascii_code <= x"2f"; -- /
when x"045" => ps2_ascii_code <= x"30"; -- 0
when x"016" => ps2_ascii_code <= x"31"; -- 1
when x"01e" => ps2_ascii_code <= x"32"; -- 2
when x"026" => ps2_ascii_code <= x"33"; -- 3
when x"025" => ps2_ascii_code <= x"34"; -- 4
when x"02e" => ps2_ascii_code <= x"35"; -- 5
when x"036" => ps2_ascii_code <= x"36"; -- 6
when x"03d" => ps2_ascii_code <= x"37"; -- 7
when x"03e" => ps2_ascii_code <= x"38"; -- 8
when x"046" => ps2_ascii_code <= x"39"; -- 9
when x"14c" => ps2_ascii_code <= x"3a"; -- :
when x"04c" => ps2_ascii_code <= x"3b"; -- ;
when x"141" => ps2_ascii_code <= x"3c"; -- <
when x"055" => ps2_ascii_code <= x"3d"; -- =
when x"149" => ps2_ascii_code <= x"3e"; -- >
when x"14a" => ps2_ascii_code <= x"3f"; -- ?
when x"11e" => ps2_ascii_code <= x"40"; -- @
when x"01c" => ps2_ascii_code <= x"41"; -- A
when x"032" => ps2_ascii_code <= x"42"; -- B
when x"021" => ps2_ascii_code <= x"43"; -- C
when x"023" => ps2_ascii_code <= x"44"; -- D
when x"024" => ps2_ascii_code <= x"45"; -- E
when x"02b" => ps2_ascii_code <= x"46"; -- F
when x"034" => ps2_ascii_code <= x"47"; -- G
when x"033" => ps2_ascii_code <= x"48"; -- H
when x"043" => ps2_ascii_code <= x"49"; -- I
when x"03b" => ps2_ascii_code <= x"4a"; -- J
when x"042" => ps2_ascii_code <= x"4b"; -- K
when x"04b" => ps2_ascii_code <= x"4c"; -- L
when x"03a" => ps2_ascii_code <= x"4d"; -- M
when x"031" => ps2_ascii_code <= x"4e"; -- N
when x"044" => ps2_ascii_code <= x"4f"; -- O
when x"04d" => ps2_ascii_code <= x"50"; -- P
when x"015" => ps2_ascii_code <= x"51"; -- Q
when x"02d" => ps2_ascii_code <= x"52"; -- R
when x"01b" => ps2_ascii_code <= x"53"; -- S
when x"02c" => ps2_ascii_code <= x"54"; -- T
when x"03c" => ps2_ascii_code <= x"55"; -- U
when x"02a" => ps2_ascii_code <= x"56"; -- V
when x"01d" => ps2_ascii_code <= x"57"; -- W
when x"022" => ps2_ascii_code <= x"58"; -- X
when x"035" => ps2_ascii_code <= x"59"; -- Y
when x"01a" => ps2_ascii_code <= x"5a"; -- Z
when x"054" => ps2_ascii_code <= x"5b"; -- [
when x"05d" => ps2_ascii_code <= x"5c"; -- \
when x"05b" => ps2_ascii_code <= x"5d"; -- ]
when x"136" => ps2_ascii_code <= x"5e"; -- ^
when x"14e" => ps2_ascii_code <= x"5f"; -- _
when x"00e" => ps2_ascii_code <= x"60"; -- `
when x"01c" => ps2_ascii_code <= x"61"; -- a
when x"032" => ps2_ascii_code <= x"62"; -- b
when x"021" => ps2_ascii_code <= x"63"; -- c
when x"023" => ps2_ascii_code <= x"64"; -- d
when x"024" => ps2_ascii_code <= x"65"; -- e
when x"02b" => ps2_ascii_code <= x"66"; -- f
when x"034" => ps2_ascii_code <= x"67"; -- g
when x"033" => ps2_ascii_code <= x"68"; -- h
when x"043" => ps2_ascii_code <= x"69"; -- i
when x"03b" => ps2_ascii_code <= x"6a"; -- j
when x"042" => ps2_ascii_code <= x"6b"; -- k
when x"04b" => ps2_ascii_code <= x"6c"; -- l
when x"03a" => ps2_ascii_code <= x"6d"; -- m
when x"031" => ps2_ascii_code <= x"6e"; -- n
when x"044" => ps2_ascii_code <= x"6f"; -- o
when x"04d" => ps2_ascii_code <= x"70"; -- p
when x"015" => ps2_ascii_code <= x"71"; -- q
when x"02d" => ps2_ascii_code <= x"72"; -- r
when x"01b" => ps2_ascii_code <= x"73"; -- s
when x"02c" => ps2_ascii_code <= x"74"; -- t
when x"03c" => ps2_ascii_code <= x"75"; -- u
when x"02a" => ps2_ascii_code <= x"76"; -- v
when x"01d" => ps2_ascii_code <= x"77"; -- w
when x"022" => ps2_ascii_code <= x"78"; -- x
when x"035" => ps2_ascii_code <= x"79"; -- y
when x"01a" => ps2_ascii_code <= x"7a"; -- z
when x"154" => ps2_ascii_code <= x"7b"; -- {
when x"15d" => ps2_ascii_code <= x"7c"; -- |
when x"15b" => ps2_ascii_code <= x"7d"; -- }
when x"10e" => ps2_ascii_code <= x"7e"; -- ~
when x"071" => ps2_ascii_code <= x"7f"; -- (Delete OR DEL on numeric keypad)
when x"171" => ps2_ascii_code <= x"7f"; -- (Delete OR DEL on numeric keypad)
when others => ps2_ascii_code <= x"FF"; -- keys not mapped
end case;
end process;
 
kbd_inst: work.keyboard port map (
keyboard_clk => keyboard_clk,
keyboard_data => keyboard_data,
clock => clock,
reset => reset,
read => read,
scan_ready => scan_ready,
scan_code => scan_code_sig
);
 
end;
/VHDL/PS2/ps2bkd.vhd
0,0 → 1,143
library IEEE;
use IEEE.std_logic_1164.all;
 
entity ps2kbd is
PORT (
keyboard_clk : inout std_logic;
keyboard_data : inout std_logic;
clock : in std_logic;
reset : in std_logic;
read : in std_logic;
scan_ready : out std_logic;
ps2_ascii_code : out std_logic_vector(7 downto 0));
end ps2kbd;
architecture rtl of ps2kbd is
 
signal scan_code_sig : std_logic_vector(7 downto 0);
signal scode_shf_sig : std_logic_vector(11 downto 0);
 
begin
 
scode_shf_sig <= "0000" & scan_code_sig;
 
ps2_ascii_decode : process(scode_shf_sig)
begin
case scode_shf_sig is
when x"066" => ps2_ascii_code <= x"08"; -- Backspace ("backspace" key)
when x"00d" => ps2_ascii_code <= x"09"; -- Horizontal Tab
when x"05a" => ps2_ascii_code <= x"0d"; -- Carriage return ("enter" key)
when x"076" => ps2_ascii_code <= x"1b"; -- Escape ("esc" key)
when x"029" => ps2_ascii_code <= x"20"; -- Space
when x"116" => ps2_ascii_code <= x"21"; -- !
when x"152" => ps2_ascii_code <= x"22"; -- "
when x"126" => ps2_ascii_code <= x"23"; -- #
when x"125" => ps2_ascii_code <= x"24"; -- $
when x"12e" => ps2_ascii_code <= x"25"; --
when x"13d" => ps2_ascii_code <= x"26"; --
when x"052" => ps2_ascii_code <= x"27"; --
when x"146" => ps2_ascii_code <= x"28"; --
when x"145" => ps2_ascii_code <= x"29"; --
when x"13e" => ps2_ascii_code <= x"2a"; -- *
when x"155" => ps2_ascii_code <= x"2b"; -- +
when x"041" => ps2_ascii_code <= x"2c"; -- ,
when x"04e" => ps2_ascii_code <= x"2d"; -- -
when x"049" => ps2_ascii_code <= x"2e"; -- .
when x"04a" => ps2_ascii_code <= x"2f"; -- /
when x"045" => ps2_ascii_code <= x"30"; -- 0
when x"016" => ps2_ascii_code <= x"31"; -- 1
when x"01e" => ps2_ascii_code <= x"32"; -- 2
when x"026" => ps2_ascii_code <= x"33"; -- 3
when x"025" => ps2_ascii_code <= x"34"; -- 4
when x"02e" => ps2_ascii_code <= x"35"; -- 5
when x"036" => ps2_ascii_code <= x"36"; -- 6
when x"03d" => ps2_ascii_code <= x"37"; -- 7
when x"03e" => ps2_ascii_code <= x"38"; -- 8
when x"046" => ps2_ascii_code <= x"39"; -- 9
when x"14c" => ps2_ascii_code <= x"3a"; -- :
when x"04c" => ps2_ascii_code <= x"3b"; -- ;
when x"141" => ps2_ascii_code <= x"3c"; -- <
when x"055" => ps2_ascii_code <= x"3d"; -- =
when x"149" => ps2_ascii_code <= x"3e"; -- >
when x"14a" => ps2_ascii_code <= x"3f"; -- ?
when x"11e" => ps2_ascii_code <= x"40"; -- @
when x"01c" => ps2_ascii_code <= x"41"; -- A
when x"032" => ps2_ascii_code <= x"42"; -- B
when x"021" => ps2_ascii_code <= x"43"; -- C
when x"023" => ps2_ascii_code <= x"44"; -- D
when x"024" => ps2_ascii_code <= x"45"; -- E
when x"02b" => ps2_ascii_code <= x"46"; -- F
when x"034" => ps2_ascii_code <= x"47"; -- G
when x"033" => ps2_ascii_code <= x"48"; -- H
when x"043" => ps2_ascii_code <= x"49"; -- I
when x"03b" => ps2_ascii_code <= x"4a"; -- J
when x"042" => ps2_ascii_code <= x"4b"; -- K
when x"04b" => ps2_ascii_code <= x"4c"; -- L
when x"03a" => ps2_ascii_code <= x"4d"; -- M
when x"031" => ps2_ascii_code <= x"4e"; -- N
when x"044" => ps2_ascii_code <= x"4f"; -- O
when x"04d" => ps2_ascii_code <= x"50"; -- P
when x"015" => ps2_ascii_code <= x"51"; -- Q
when x"02d" => ps2_ascii_code <= x"52"; -- R
when x"01b" => ps2_ascii_code <= x"53"; -- S
when x"02c" => ps2_ascii_code <= x"54"; -- T
when x"03c" => ps2_ascii_code <= x"55"; -- U
when x"02a" => ps2_ascii_code <= x"56"; -- V
when x"01d" => ps2_ascii_code <= x"57"; -- W
when x"022" => ps2_ascii_code <= x"58"; -- X
when x"035" => ps2_ascii_code <= x"59"; -- Y
when x"01a" => ps2_ascii_code <= x"5a"; -- Z
when x"054" => ps2_ascii_code <= x"5b"; -- [
when x"05d" => ps2_ascii_code <= x"5c"; -- \
when x"05b" => ps2_ascii_code <= x"5d"; -- ]
when x"136" => ps2_ascii_code <= x"5e"; -- ^
when x"14e" => ps2_ascii_code <= x"5f"; -- _
when x"00e" => ps2_ascii_code <= x"60"; -- `
when x"11c" => ps2_ascii_code <= x"61"; -- a
when x"132" => ps2_ascii_code <= x"62"; -- b
when x"121" => ps2_ascii_code <= x"63"; -- c
when x"123" => ps2_ascii_code <= x"64"; -- d
when x"124" => ps2_ascii_code <= x"65"; -- e
when x"12b" => ps2_ascii_code <= x"66"; -- f
when x"134" => ps2_ascii_code <= x"67"; -- g
when x"133" => ps2_ascii_code <= x"68"; -- h
when x"143" => ps2_ascii_code <= x"69"; -- i
when x"13b" => ps2_ascii_code <= x"6a"; -- j
when x"142" => ps2_ascii_code <= x"6b"; -- k
when x"14b" => ps2_ascii_code <= x"6c"; -- l
when x"13a" => ps2_ascii_code <= x"6d"; -- m
when x"131" => ps2_ascii_code <= x"6e"; -- n
when x"144" => ps2_ascii_code <= x"6f"; -- o
when x"14d" => ps2_ascii_code <= x"70"; -- p
when x"115" => ps2_ascii_code <= x"71"; -- q
when x"12d" => ps2_ascii_code <= x"72"; -- r
when x"11b" => ps2_ascii_code <= x"73"; -- s
when x"12c" => ps2_ascii_code <= x"74"; -- t
when x"13c" => ps2_ascii_code <= x"75"; -- u
when x"12a" => ps2_ascii_code <= x"76"; -- v
when x"11d" => ps2_ascii_code <= x"77"; -- w
when x"122" => ps2_ascii_code <= x"78"; -- x
when x"135" => ps2_ascii_code <= x"79"; -- y
when x"11a" => ps2_ascii_code <= x"7a"; -- z
when x"154" => ps2_ascii_code <= x"7b"; -- {
when x"15d" => ps2_ascii_code <= x"7c"; -- |
when x"15b" => ps2_ascii_code <= x"7d"; -- }
when x"10e" => ps2_ascii_code <= x"7e"; -- ~
when x"071" => ps2_ascii_code <= x"7f"; -- (Delete OR DEL on numeric keypad)
when x"171" => ps2_ascii_code <= x"7f"; -- (Delete OR DEL on numeric keypad)
when others => ps2_ascii_code <= x"FF"; -- keys not mapped
end case;
end process;
 
kbd_inst: work.keyboard port map (
keyboard_clk => keyboard_clk,
keyboard_data => keyboard_data,
clock => clock,
reset => reset,
read => read,
scan_ready => scan_ready,
scan_code => scan_code_sig
);
 
end;
/VHDL/PS2/KEYBOARD.VHD
0,0 → 1,78
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.all;
USE IEEE.STD_LOGIC_ARITH.all;
USE IEEE.STD_LOGIC_UNSIGNED.all;
 
ENTITY keyboard IS
PORT( keyboard_clk, keyboard_data, clock ,
reset, read : IN STD_LOGIC;
scan_code : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
scan_ready : OUT STD_LOGIC);
END keyboard;
 
ARCHITECTURE a OF keyboard IS
SIGNAL INCNT : std_logic_vector(3 downto 0);
SIGNAL SHIFTIN : std_logic_vector(8 downto 0);
SIGNAL READ_CHAR, clock_enable : std_logic;
SIGNAL INFLAG, ready_set : std_logic;
SIGNAL keyboard_clk_filtered : std_logic;
SIGNAL filter : std_logic_vector(7 downto 0);
BEGIN
 
PROCESS (read, ready_set)
BEGIN
IF read = '1' THEN scan_ready <= '0';
ELSIF ready_set'EVENT and ready_set = '1' THEN
scan_ready <= '1';
END IF;
END PROCESS;
 
 
--This process filters the raw clock signal coming from the keyboard using a shift register and two AND gates
Clock_filter: PROCESS
BEGIN
WAIT UNTIL clock'EVENT AND clock= '1';
clock_enable <= NOT clock_enable;
IF clock_enable = '1' THEN
filter (6 DOWNTO 0) <= filter(7 DOWNTO 1) ;
filter(7) <= keyboard_clk;
IF filter = "11111111" THEN keyboard_clk_filtered <= '1';
ELSIF filter= "00000000" THEN keyboard_clk_filtered <= '0';
END IF;
END IF;
END PROCESS Clock_filter;
 
 
--This process reads in serial data coming from the terminal
PROCESS
BEGIN
WAIT UNTIL (KEYBOARD_CLK_filtered'EVENT AND KEYBOARD_CLK_filtered='1');
IF RESET='0' THEN
INCNT <= "0000";
READ_CHAR <= '0';
ready_set<= '0';
ELSE
IF KEYBOARD_DATA='0' AND READ_CHAR='0' THEN
READ_CHAR<= '1';
ready_set<= '0';
ELSE
-- Shift in next 8 data bits to assemble a scan code
IF READ_CHAR = '1' THEN
IF INCNT < "1001" THEN
INCNT <= INCNT + 1;
SHIFTIN(7 DOWNTO 0) <= SHIFTIN(8 DOWNTO 1);
SHIFTIN(8) <= KEYBOARD_DATA;
-- End of scan code character, so set flags and exit loop
ELSE
scan_code <= SHIFTIN(7 DOWNTO 0);
READ_CHAR <= '0';
ready_set <= '1';
INCNT <= "0000";
END IF;
END IF;
END IF;
END IF;
END PROCESS;
END a;
 
 
/VHDL/rom.vhd
0,0 → 1,568
library IEEE;
use IEEE.std_logic_1164.all;
use ieee.numeric_std.all;
 
entity rom is
port(
Clk : in std_logic;
A : in std_logic_vector(15 downto 0);
D : out std_logic_vector(7 downto 0)
);
end rom;
 
architecture rtl of rom is
begin
 
process (Clk)
begin
if Clk'event and Clk = '1' then
case A is
when x"0000" => D <= x"31";
when x"0001" => D <= x"FF";
when x"0002" => D <= x"FF";
when x"0003" => D <= x"CD";
when x"0004" => D <= x"C7";
when x"0005" => D <= x"00";
when x"0006" => D <= x"21";
when x"0007" => D <= x"32";
when x"0008" => D <= x"20";
when x"0009" => D <= x"11";
when x"000A" => D <= x"0E";
when x"000B" => D <= x"01";
when x"000C" => D <= x"CD";
when x"000D" => D <= x"D7";
when x"000E" => D <= x"00";
when x"000F" => D <= x"21";
when x"0010" => D <= x"5A";
when x"0011" => D <= x"20";
when x"0012" => D <= x"11";
when x"0013" => D <= x"21";
when x"0014" => D <= x"01";
when x"0015" => D <= x"CD";
when x"0016" => D <= x"D7";
when x"0017" => D <= x"00";
when x"0018" => D <= x"CD";
when x"0019" => D <= x"E8";
when x"001A" => D <= x"00";
when x"001B" => D <= x"21";
when x"001C" => D <= x"46";
when x"001D" => D <= x"21";
when x"001E" => D <= x"11";
when x"001F" => D <= x"34";
when x"0020" => D <= x"01";
when x"0021" => D <= x"CD";
when x"0022" => D <= x"D7";
when x"0023" => D <= x"00";
when x"0024" => D <= x"21";
when x"0025" => D <= x"96";
when x"0026" => D <= x"21";
when x"0027" => D <= x"11";
when x"0028" => D <= x"50";
when x"0029" => D <= x"01";
when x"002A" => D <= x"CD";
when x"002B" => D <= x"D7";
when x"002C" => D <= x"00";
when x"002D" => D <= x"21";
when x"002E" => D <= x"E6";
when x"002F" => D <= x"21";
when x"0030" => D <= x"11";
when x"0031" => D <= x"6D";
when x"0032" => D <= x"01";
when x"0033" => D <= x"CD";
when x"0034" => D <= x"D7";
when x"0035" => D <= x"00";
when x"0036" => D <= x"21";
when x"0037" => D <= x"36";
when x"0038" => D <= x"22";
when x"0039" => D <= x"11";
when x"003A" => D <= x"8A";
when x"003B" => D <= x"01";
when x"003C" => D <= x"CD";
when x"003D" => D <= x"D7";
when x"003E" => D <= x"00";
when x"003F" => D <= x"21";
when x"0040" => D <= x"5E";
when x"0041" => D <= x"22";
when x"0042" => D <= x"11";
when x"0043" => D <= x"9E";
when x"0044" => D <= x"01";
when x"0045" => D <= x"CD";
when x"0046" => D <= x"D7";
when x"0047" => D <= x"00";
when x"0048" => D <= x"DB";
when x"0049" => D <= x"20";
when x"004A" => D <= x"32";
when x"004B" => D <= x"00";
when x"004C" => D <= x"E0";
when x"004D" => D <= x"11";
when x"004E" => D <= x"D6";
when x"004F" => D <= x"22";
when x"0050" => D <= x"01";
when x"0051" => D <= x"1E";
when x"0052" => D <= x"00";
when x"0053" => D <= x"CD";
when x"0054" => D <= x"DF";
when x"0055" => D <= x"00";
when x"0056" => D <= x"FE";
when x"0057" => D <= x"41";
when x"0058" => D <= x"28";
when x"0059" => D <= x"0B";
when x"005A" => D <= x"D3";
when x"005B" => D <= x"11";
when x"005C" => D <= x"12";
when x"005D" => D <= x"13";
when x"005E" => D <= x"0B";
when x"005F" => D <= x"78";
when x"0060" => D <= x"B1";
when x"0061" => D <= x"28";
when x"0062" => D <= x"EA";
when x"0063" => D <= x"18";
when x"0064" => D <= x"EE";
when x"0065" => D <= x"21";
when x"0066" => D <= x"00";
when x"0067" => D <= x"40";
when x"0068" => D <= x"3E";
when x"0069" => D <= x"00";
when x"006A" => D <= x"77";
when x"006B" => D <= x"23";
when x"006C" => D <= x"3C";
when x"006D" => D <= x"20";
when x"006E" => D <= x"FB";
when x"006F" => D <= x"3E";
when x"0070" => D <= x"01";
when x"0071" => D <= x"D3";
when x"0072" => D <= x"01";
when x"0073" => D <= x"CD";
when x"0074" => D <= x"B9";
when x"0075" => D <= x"00";
when x"0076" => D <= x"CD";
when x"0077" => D <= x"B9";
when x"0078" => D <= x"00";
when x"0079" => D <= x"CD";
when x"007A" => D <= x"B9";
when x"007B" => D <= x"00";
when x"007C" => D <= x"CD";
when x"007D" => D <= x"A6";
when x"007E" => D <= x"00";
when x"007F" => D <= x"CD";
when x"0080" => D <= x"B9";
when x"0081" => D <= x"00";
when x"0082" => D <= x"CD";
when x"0083" => D <= x"A6";
when x"0084" => D <= x"00";
when x"0085" => D <= x"21";
when x"0086" => D <= x"00";
when x"0087" => D <= x"40";
when x"0088" => D <= x"7C";
when x"0089" => D <= x"D3";
when x"008A" => D <= x"11";
when x"008B" => D <= x"7D";
when x"008C" => D <= x"D3";
when x"008D" => D <= x"10";
when x"008E" => D <= x"7E";
when x"008F" => D <= x"D3";
when x"0090" => D <= x"01";
when x"0091" => D <= x"CD";
when x"0092" => D <= x"B9";
when x"0093" => D <= x"00";
when x"0094" => D <= x"23";
when x"0095" => D <= x"7E";
when x"0096" => D <= x"FE";
when x"0097" => D <= x"FF";
when x"0098" => D <= x"20";
when x"0099" => D <= x"EE";
when x"009A" => D <= x"3E";
when x"009B" => D <= x"00";
when x"009C" => D <= x"D3";
when x"009D" => D <= x"01";
when x"009E" => D <= x"D3";
when x"009F" => D <= x"02";
when x"00A0" => D <= x"CD";
when x"00A1" => D <= x"A6";
when x"00A2" => D <= x"00";
when x"00A3" => D <= x"C3";
when x"00A4" => D <= x"03";
when x"00A5" => D <= x"00";
when x"00A6" => D <= x"CD";
when x"00A7" => D <= x"B9";
when x"00A8" => D <= x"00";
when x"00A9" => D <= x"DB";
when x"00AA" => D <= x"30";
when x"00AB" => D <= x"D3";
when x"00AC" => D <= x"10";
when x"00AD" => D <= x"FE";
when x"00AE" => D <= x"0E";
when x"00AF" => D <= x"20";
when x"00B0" => D <= x"F5";
when x"00B1" => D <= x"C9";
when x"00B2" => D <= x"3A";
when x"00B3" => D <= x"00";
when x"00B4" => D <= x"E0";
when x"00B5" => D <= x"3D";
when x"00B6" => D <= x"20";
when x"00B7" => D <= x"FD";
when x"00B8" => D <= x"C9";
when x"00B9" => D <= x"3A";
when x"00BA" => D <= x"00";
when x"00BB" => D <= x"E0";
when x"00BC" => D <= x"F5";
when x"00BD" => D <= x"3E";
when x"00BE" => D <= x"FF";
when x"00BF" => D <= x"3D";
when x"00C0" => D <= x"20";
when x"00C1" => D <= x"FD";
when x"00C2" => D <= x"F1";
when x"00C3" => D <= x"3D";
when x"00C4" => D <= x"20";
when x"00C5" => D <= x"F6";
when x"00C6" => D <= x"C9";
when x"00C7" => D <= x"21";
when x"00C8" => D <= x"00";
when x"00C9" => D <= x"20";
when x"00CA" => D <= x"11";
when x"00CB" => D <= x"B0";
when x"00CC" => D <= x"04";
when x"00CD" => D <= x"3E";
when x"00CE" => D <= x"20";
when x"00CF" => D <= x"77";
when x"00D0" => D <= x"23";
when x"00D1" => D <= x"1B";
when x"00D2" => D <= x"7A";
when x"00D3" => D <= x"B3";
when x"00D4" => D <= x"20";
when x"00D5" => D <= x"F7";
when x"00D6" => D <= x"C9";
when x"00D7" => D <= x"1A";
when x"00D8" => D <= x"B7";
when x"00D9" => D <= x"C8";
when x"00DA" => D <= x"77";
when x"00DB" => D <= x"23";
when x"00DC" => D <= x"13";
when x"00DD" => D <= x"18";
when x"00DE" => D <= x"F8";
when x"00DF" => D <= x"CD";
when x"00E0" => D <= x"B9";
when x"00E1" => D <= x"00";
when x"00E2" => D <= x"DB";
when x"00E3" => D <= x"80";
when x"00E4" => D <= x"B7";
when x"00E5" => D <= x"28";
when x"00E6" => D <= x"F8";
when x"00E7" => D <= x"C9";
when x"00E8" => D <= x"11";
when x"00E9" => D <= x"BD";
when x"00EA" => D <= x"01";
when x"00EB" => D <= x"21";
when x"00EC" => D <= x"F5";
when x"00ED" => D <= x"20";
when x"00EE" => D <= x"CD";
when x"00EF" => D <= x"D7";
when x"00F0" => D <= x"00";
when x"00F1" => D <= x"21";
when x"00F2" => D <= x"1D";
when x"00F3" => D <= x"21";
when x"00F4" => D <= x"3E";
when x"00F5" => D <= x"0A";
when x"00F6" => D <= x"11";
when x"00F7" => D <= x"FF";
when x"00F8" => D <= x"01";
when x"00F9" => D <= x"F5";
when x"00FA" => D <= x"E5";
when x"00FB" => D <= x"CD";
when x"00FC" => D <= x"D7";
when x"00FD" => D <= x"00";
when x"00FE" => D <= x"E1";
when x"00FF" => D <= x"F1";
when x"0100" => D <= x"01";
when x"0101" => D <= x"28";
when x"0102" => D <= x"00";
when x"0103" => D <= x"09";
when x"0104" => D <= x"3D";
when x"0105" => D <= x"20";
when x"0106" => D <= x"EF";
when x"0107" => D <= x"11";
when x"0108" => D <= x"DE";
when x"0109" => D <= x"01";
when x"010A" => D <= x"CD";
when x"010B" => D <= x"D7";
when x"010C" => D <= x"00";
when x"010D" => D <= x"C9";
when x"010E" => D <= x"5A";
when x"010F" => D <= x"38";
when x"0110" => D <= x"30";
when x"0111" => D <= x"20";
when x"0112" => D <= x"53";
when x"0113" => D <= x"59";
when x"0114" => D <= x"53";
when x"0115" => D <= x"54";
when x"0116" => D <= x"45";
when x"0117" => D <= x"4D";
when x"0118" => D <= x"20";
when x"0119" => D <= x"4F";
when x"011A" => D <= x"4E";
when x"011B" => D <= x"20";
when x"011C" => D <= x"43";
when x"011D" => D <= x"48";
when x"011E" => D <= x"49";
when x"011F" => D <= x"50";
when x"0120" => D <= x"00";
when x"0121" => D <= x"52";
when x"0122" => D <= x"4F";
when x"0123" => D <= x"4E";
when x"0124" => D <= x"49";
when x"0125" => D <= x"56";
when x"0126" => D <= x"4F";
when x"0127" => D <= x"4E";
when x"0128" => D <= x"20";
when x"0129" => D <= x"43";
when x"012A" => D <= x"4F";
when x"012B" => D <= x"53";
when x"012C" => D <= x"54";
when x"012D" => D <= x"41";
when x"012E" => D <= x"20";
when x"012F" => D <= x"32";
when x"0130" => D <= x"30";
when x"0131" => D <= x"30";
when x"0132" => D <= x"38";
when x"0133" => D <= x"00";
when x"0134" => D <= x"20";
when x"0135" => D <= x"20";
when x"0136" => D <= x"7C";
when x"0137" => D <= x"21";
when x"0138" => D <= x"23";
when x"0139" => D <= x"24";
when x"013A" => D <= x"25";
when x"013B" => D <= x"26";
when x"013C" => D <= x"2F";
when x"013D" => D <= x"28";
when x"013E" => D <= x"29";
when x"013F" => D <= x"3D";
when x"0140" => D <= x"3F";
when x"0141" => D <= x"2A";
when x"0142" => D <= x"60";
when x"0143" => D <= x"2B";
when x"0144" => D <= x"B4";
when x"0145" => D <= x"E7";
when x"0146" => D <= x"7E";
when x"0147" => D <= x"5E";
when x"0148" => D <= x"2C";
when x"0149" => D <= x"2E";
when x"014A" => D <= x"3B";
when x"014B" => D <= x"3A";
when x"014C" => D <= x"5C";
when x"014D" => D <= x"3C";
when x"014E" => D <= x"3E";
when x"014F" => D <= x"00";
when x"0150" => D <= x"20";
when x"0151" => D <= x"20";
when x"0152" => D <= x"41";
when x"0153" => D <= x"42";
when x"0154" => D <= x"43";
when x"0155" => D <= x"44";
when x"0156" => D <= x"45";
when x"0157" => D <= x"46";
when x"0158" => D <= x"47";
when x"0159" => D <= x"48";
when x"015A" => D <= x"49";
when x"015B" => D <= x"4A";
when x"015C" => D <= x"4B";
when x"015D" => D <= x"4C";
when x"015E" => D <= x"4D";
when x"015F" => D <= x"4E";
when x"0160" => D <= x"4F";
when x"0161" => D <= x"50";
when x"0162" => D <= x"51";
when x"0163" => D <= x"52";
when x"0164" => D <= x"53";
when x"0165" => D <= x"54";
when x"0166" => D <= x"55";
when x"0167" => D <= x"56";
when x"0168" => D <= x"57";
when x"0169" => D <= x"58";
when x"016A" => D <= x"59";
when x"016B" => D <= x"5A";
when x"016C" => D <= x"00";
when x"016D" => D <= x"20";
when x"016E" => D <= x"20";
when x"016F" => D <= x"61";
when x"0170" => D <= x"62";
when x"0171" => D <= x"63";
when x"0172" => D <= x"64";
when x"0173" => D <= x"65";
when x"0174" => D <= x"66";
when x"0175" => D <= x"67";
when x"0176" => D <= x"68";
when x"0177" => D <= x"69";
when x"0178" => D <= x"6A";
when x"0179" => D <= x"6B";
when x"017A" => D <= x"6C";
when x"017B" => D <= x"6D";
when x"017C" => D <= x"6E";
when x"017D" => D <= x"6F";
when x"017E" => D <= x"70";
when x"017F" => D <= x"71";
when x"0180" => D <= x"72";
when x"0181" => D <= x"73";
when x"0182" => D <= x"74";
when x"0183" => D <= x"75";
when x"0184" => D <= x"76";
when x"0185" => D <= x"77";
when x"0186" => D <= x"78";
when x"0187" => D <= x"79";
when x"0188" => D <= x"7A";
when x"0189" => D <= x"00";
when x"018A" => D <= x"20";
when x"018B" => D <= x"20";
when x"018C" => D <= x"20";
when x"018D" => D <= x"20";
when x"018E" => D <= x"20";
when x"018F" => D <= x"20";
when x"0190" => D <= x"20";
when x"0191" => D <= x"20";
when x"0192" => D <= x"20";
when x"0193" => D <= x"30";
when x"0194" => D <= x"31";
when x"0195" => D <= x"32";
when x"0196" => D <= x"33";
when x"0197" => D <= x"34";
when x"0198" => D <= x"35";
when x"0199" => D <= x"36";
when x"019A" => D <= x"37";
when x"019B" => D <= x"38";
when x"019C" => D <= x"39";
when x"019D" => D <= x"00";
when x"019E" => D <= x"02";
when x"019F" => D <= x"03";
when x"01A0" => D <= x"04";
when x"01A1" => D <= x"0B";
when x"01A2" => D <= x"0C";
when x"01A3" => D <= x"0D";
when x"01A4" => D <= x"0E";
when x"01A5" => D <= x"12";
when x"01A6" => D <= x"18";
when x"01A7" => D <= x"19";
when x"01A8" => D <= x"1A";
when x"01A9" => D <= x"1B";
when x"01AA" => D <= x"E8";
when x"01AB" => D <= x"E9";
when x"01AC" => D <= x"EB";
when x"01AD" => D <= x"BB";
when x"01AE" => D <= x"BC";
when x"01AF" => D <= x"8A";
when x"01B0" => D <= x"86";
when x"01B1" => D <= x"87";
when x"01B2" => D <= x"81";
when x"01B3" => D <= x"80";
when x"01B4" => D <= x"01";
when x"01B5" => D <= x"06";
when x"01B6" => D <= x"07";
when x"01B7" => D <= x"08";
when x"01B8" => D <= x"09";
when x"01B9" => D <= x"0A";
when x"01BA" => D <= x"1D";
when x"01BB" => D <= x"1F";
when x"01BC" => D <= x"00";
when x"01BD" => D <= x"C9";
when x"01BE" => D <= x"CD";
when x"01BF" => D <= x"CD";
when x"01C0" => D <= x"CD";
when x"01C1" => D <= x"CD";
when x"01C2" => D <= x"CD";
when x"01C3" => D <= x"CD";
when x"01C4" => D <= x"CD";
when x"01C5" => D <= x"CD";
when x"01C6" => D <= x"CD";
when x"01C7" => D <= x"CD";
when x"01C8" => D <= x"CD";
when x"01C9" => D <= x"CD";
when x"01CA" => D <= x"CD";
when x"01CB" => D <= x"CD";
when x"01CC" => D <= x"CD";
when x"01CD" => D <= x"CD";
when x"01CE" => D <= x"CD";
when x"01CF" => D <= x"CD";
when x"01D0" => D <= x"CD";
when x"01D1" => D <= x"CD";
when x"01D2" => D <= x"CD";
when x"01D3" => D <= x"CD";
when x"01D4" => D <= x"CD";
when x"01D5" => D <= x"CD";
when x"01D6" => D <= x"CD";
when x"01D7" => D <= x"CD";
when x"01D8" => D <= x"CD";
when x"01D9" => D <= x"CD";
when x"01DA" => D <= x"CD";
when x"01DB" => D <= x"CD";
when x"01DC" => D <= x"BB";
when x"01DD" => D <= x"00";
when x"01DE" => D <= x"C8";
when x"01DF" => D <= x"CD";
when x"01E0" => D <= x"CD";
when x"01E1" => D <= x"CD";
when x"01E2" => D <= x"CD";
when x"01E3" => D <= x"CD";
when x"01E4" => D <= x"CD";
when x"01E5" => D <= x"CD";
when x"01E6" => D <= x"CD";
when x"01E7" => D <= x"CD";
when x"01E8" => D <= x"CD";
when x"01E9" => D <= x"CD";
when x"01EA" => D <= x"CD";
when x"01EB" => D <= x"CD";
when x"01EC" => D <= x"CD";
when x"01ED" => D <= x"CD";
when x"01EE" => D <= x"CD";
when x"01EF" => D <= x"CD";
when x"01F0" => D <= x"CD";
when x"01F1" => D <= x"CD";
when x"01F2" => D <= x"CD";
when x"01F3" => D <= x"CD";
when x"01F4" => D <= x"CD";
when x"01F5" => D <= x"CD";
when x"01F6" => D <= x"CD";
when x"01F7" => D <= x"CD";
when x"01F8" => D <= x"CD";
when x"01F9" => D <= x"CD";
when x"01FA" => D <= x"CD";
when x"01FB" => D <= x"CD";
when x"01FC" => D <= x"CD";
when x"01FD" => D <= x"BC";
when x"01FE" => D <= x"00";
when x"01FF" => D <= x"BA";
when x"0200" => D <= x"20";
when x"0201" => D <= x"20";
when x"0202" => D <= x"20";
when x"0203" => D <= x"20";
when x"0204" => D <= x"20";
when x"0205" => D <= x"20";
when x"0206" => D <= x"20";
when x"0207" => D <= x"20";
when x"0208" => D <= x"20";
when x"0209" => D <= x"20";
when x"020A" => D <= x"20";
when x"020B" => D <= x"20";
when x"020C" => D <= x"20";
when x"020D" => D <= x"20";
when x"020E" => D <= x"20";
when x"020F" => D <= x"20";
when x"0210" => D <= x"20";
when x"0211" => D <= x"20";
when x"0212" => D <= x"20";
when x"0213" => D <= x"20";
when x"0214" => D <= x"20";
when x"0215" => D <= x"20";
when x"0216" => D <= x"20";
when x"0217" => D <= x"20";
when x"0218" => D <= x"20";
when x"0219" => D <= x"20";
when x"021A" => D <= x"20";
when x"021B" => D <= x"20";
when x"021C" => D <= x"20";
when x"021D" => D <= x"20";
when x"021E" => D <= x"BA";
when x"021F" => D <= x"00";
when others => D <= x"00";
end case;
end if;
end process;
end;
/VHDL/VIDEO_80X40.vhd
0,0 → 1,81
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
-- use IEEE.std_logic_arith.all;
use IEEE.numeric_std.all;
--use IEEE.std_logic_signed.all;
--use IEEE.math_real.all;
--use IEEE.math_complex.all;
 
 
ENTITY video_80x40 is
PORT( CLOCK_50 : IN STD_LOGIC;
VRAM_DATA : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
VRAM_ADDR : OUT STD_LOGIC_VECTOR(12 DOWNTO 0);
VRAM_CLOCK : OUT STD_LOGIC;
VRAM_WREN : OUT STD_LOGIC;
VGA_R,
VGA_G,
VGA_B : OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
VGA_HS,
VGA_VS : OUT STD_LOGIC);
END video_80x40;
 
ARCHITECTURE A OF video_80x40 IS
 
-- Added for VDU support
signal Clock_video : std_logic;
signal VGA_R_sig : std_logic_vector(3 downto 0);
signal VGA_G_sig : std_logic_vector(3 downto 0);
signal VGA_B_sig : std_logic_vector(3 downto 0);
signal pixel_row_sig : std_logic_vector(9 downto 0);
signal pixel_column_sig : std_logic_vector(9 downto 0);
signal pixel_clock_sig : std_logic;
signal char_addr_sig : std_logic_vector(7 downto 0);
signal font_row_sig : std_logic_vector(2 downto 0);
signal font_col_sig : std_logic_vector(2 downto 0);
signal pixel_sig : std_logic;
signal video_on_sig : std_logic;
BEGIN
VGA_R_sig <= "0000";
VGA_G_sig <= "0000";
VGA_B_sig <= pixel_sig & pixel_sig & pixel_sig & pixel_sig;
VRAM_WREN <= video_on_sig;
VRAM_CLOCK <= pixel_clock_sig;
VRAM_ADDR <= (pixel_row_sig(9 downto 4) * "0101000" + pixel_column_sig(9 downto 4));
-- Fonts ROM read
char_addr_sig <= VRAM_DATA;
font_row_sig(2 downto 0) <= pixel_row_sig(3 downto 1);
font_col_sig(2 downto 0) <= pixel_column_sig(3 downto 1);
vga_sync_inst : work.vga_sync
port map (
clock_50Mhz => CLOCK_50,
red => VGA_R_sig,
green => VGA_G_sig,
blue => VGA_B_sig,
red_out => VGA_R,
green_out => VGA_G,
blue_out => VGA_B,
horiz_sync_out => VGA_HS,
vert_sync_out => VGA_VS,
video_on => video_on_sig,
pixel_clock => pixel_clock_sig,
pixel_row => pixel_row_sig,
pixel_column => pixel_column_sig
);
 
char_rom_inst : work.char_rom
port map (
clock => pixel_clock_sig,
character_address => char_addr_sig,
font_row => font_row_sig,
font_col => font_col_sig,
rom_mux_output => pixel_sig
);
END A;
/VHDL/CHAR_ROM.VHD
0,0 → 1,36
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_ARITH.all;
use IEEE.STD_LOGIC_UNSIGNED.all;
LIBRARY lpm;
USE lpm.lpm_components.ALL;
 
ENTITY Char_ROM IS
PORT( clock : IN STD_LOGIC;
character_address : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
font_row, font_col : IN STD_LOGIC_VECTOR(2 DOWNTO 0);
rom_mux_output : OUT STD_LOGIC);
END Char_ROM;
 
ARCHITECTURE a OF Char_ROM IS
SIGNAL rom_data: STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL rom_address: STD_LOGIC_VECTOR(10 DOWNTO 0);
BEGIN
-- Small 8 by 8 Character Generator ROM for Video Display
-- Each character is 8 8-bits words of pixel data
char_gen_rom: lpm_rom
GENERIC MAP ( lpm_widthad => 11,
lpm_numwords => 2048,
lpm_outdata => "UNREGISTERED",
lpm_address_control => "REGISTERED",
-- Reads in mif file for character generator font data
lpm_file => "..\..\ROM\CHARROM.MIF",
lpm_width => 8)
PORT MAP ( inclock => clock, address => rom_address, q => rom_data);
 
rom_address <= character_address & font_row;
-- Mux to pick off correct rom data bit from 8-bit word
-- for on screen character generation
rom_mux_output <= rom_data ( (CONV_INTEGER(NOT font_col(2 downto 0))));
 
END a;
/VHDL/top_de1.vhd
0,0 → 1,505
-------------------------------------------------------------------------------------------------
-- Z80_Soc (Z80 System on Chip)
--
-- Version 0.5 Beta
--
-- Developer: Ronivon Candido Costa
-- Release Date: 2008 / 04 / 16
--
-- Based on the T80 core: http://www.opencores.org/projects.cgi/web/t80
-- This version developed and tested on: Altera DE1 Development Board
--
-- Please, see the RevisionHistory.txt file for complete features and change history.
--
-- Peripherals configured (Using Ports):
--
-- 08 KB Internal ROM Read (0x0000h - 0x1FFFh)
-- 08 KB INTERNAL VRAM Write (0x2000h - 0x3FFFh)
-- 48 KB External SRAM Read/Write (0x4000h - 0xFFFFh)
-- 08 Green Leds Out (Port 0x01h)
-- 08 Red Leds Out (Port 0x02h)
-- 04 Seven Seg displays Out (Ports 0x10h and 0x11h)
-- 36 Pins GPIO0 In/Out (Ports 0xA0h, 0xA1h, 0xA2h, 0xA3h, 0xA4h, 0xC0h)
-- 36 Pins GPIO1 In/Out (Ports 0xB0h, 0xB1h, 0xB2h, 0xB3h, 0xB4h, 0xC1h)
-- 08 Switches In (Port 0x20h)
-- 04 Push buttons In (Port 0x30h)
-- PS/2 keyboard In (Port 0x80h)
-- Video Out 40x30 (VGA) Out (0x2000h - 0x24B0)
--
-- TO-DO:
-- - Monitor program to introduce Z80 Assmebly codes and run
-- - Serial communication, to download assembly code from PC
-- - Add hardware support for 80x40 Video out
-- - SD/MMC card interface to read/store data and programs
-------------------------------------------------------------------------------------------------
 
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;
 
entity TOP_DE1 is
port(
 
-- Clocks
CLOCK_27, -- 27 MHz
CLOCK_50, -- 50 MHz
EXT_CLOCK : in std_logic; -- External Clock
 
-- Buttons and switches
KEY : in std_logic_vector(3 downto 0); -- Push buttons
SW : in std_logic_vector(9 downto 0); -- Switches
 
-- LED displays
HEX0, HEX1, HEX2, HEX3 -- 7-segment displays
: out std_logic_vector(6 downto 0);
LEDG : out std_logic_vector(7 downto 0); -- Green LEDs
LEDR : out std_logic_vector(9 downto 0); -- Red LEDs
 
-- RS-232 interface
UART_TXD : out std_logic; -- UART transmitter
UART_RXD : in std_logic; -- UART receiver
 
-- IRDA interface
 
-- IRDA_TXD : out std_logic; -- IRDA Transmitter
IRDA_RXD : in std_logic; -- IRDA Receiver
 
-- SDRAM
DRAM_DQ : inout std_logic_vector(15 downto 0); -- Data Bus
DRAM_ADDR : out std_logic_vector(11 downto 0); -- Address Bus
DRAM_LDQM, -- Low-byte Data Mask
DRAM_UDQM, -- High-byte Data Mask
DRAM_WE_N, -- Write Enable
DRAM_CAS_N, -- Column Address Strobe
DRAM_RAS_N, -- Row Address Strobe
DRAM_CS_N, -- Chip Select
DRAM_BA_0, -- Bank Address 0
DRAM_BA_1, -- Bank Address 0
DRAM_CLK, -- Clock
DRAM_CKE : out std_logic; -- Clock Enable
 
-- FLASH
FL_DQ : inout std_logic_vector(7 downto 0); -- Data bus
FL_ADDR : out std_logic_vector(21 downto 0); -- Address bus
FL_WE_N, -- Write Enable
FL_RST_N, -- Reset
FL_OE_N, -- Output Enable
FL_CE_N : out std_logic; -- Chip Enable
 
-- SRAM
SRAM_DQ : inout std_logic_vector(15 downto 0); -- Data bus 16 Bits
SRAM_ADDR : out std_logic_vector(17 downto 0); -- Address bus 18 Bits
SRAM_UB_N, -- High-byte Data Mask
SRAM_LB_N, -- Low-byte Data Mask
SRAM_WE_N, -- Write Enable
SRAM_CE_N, -- Chip Enable
SRAM_OE_N : out std_logic; -- Output Enable
 
-- SD card interface
SD_DAT : in std_logic; -- SD Card Data SD pin 7 "DAT 0/DataOut"
SD_DAT3 : out std_logic; -- SD Card Data 3 SD pin 1 "DAT 3/nCS"
SD_CMD : out std_logic; -- SD Card Command SD pin 2 "CMD/DataIn"
SD_CLK : out std_logic; -- SD Card Clock SD pin 5 "CLK"
 
-- USB JTAG link
TDI, -- CPLD -> FPGA (data in)
TCK, -- CPLD -> FPGA (clk)
TCS : in std_logic; -- CPLD -> FPGA (CS)
TDO : out std_logic; -- FPGA -> CPLD (data out)
 
-- I2C bus
I2C_SDAT : inout std_logic; -- I2C Data
I2C_SCLK : out std_logic; -- I2C Clock
 
-- PS/2 port
PS2_DAT, -- Data
PS2_CLK : inout std_logic; -- Clock
 
-- VGA output
VGA_HS, -- H_SYNC
VGA_VS : out std_logic; -- SYNC
VGA_R, -- Red[3:0]
VGA_G, -- Green[3:0]
VGA_B : out std_logic_vector(3 downto 0); -- Blue[3:0]
-- Audio CODEC
AUD_ADCLRCK : inout std_logic; -- ADC LR Clock
AUD_ADCDAT : in std_logic; -- ADC Data
AUD_DACLRCK : inout std_logic; -- DAC LR Clock
AUD_DACDAT : out std_logic; -- DAC Data
AUD_BCLK : inout std_logic; -- Bit-Stream Clock
AUD_XCK : out std_logic; -- Chip Clock
-- General-purpose I/O
GPIO_0, -- GPIO Connection 0
GPIO_1 : inout std_logic_vector(35 downto 0) -- GPIO Connection 1
);
end TOP_DE1;
 
architecture rtl of TOP_DE1 is
 
component T80s
generic(
Mode : integer := 0);
port (
RESET_n : in std_logic;
CLK_n : in std_logic;
WAIT_n : in std_logic;
INT_n : in std_logic;
NMI_n : in std_logic;
BUSRQ_n : in std_logic;
M1_n : out std_logic;
MREQ_n : out std_logic;
IORQ_n : out std_logic;
RD_n : out std_logic;
WR_n : out std_logic;
RFSH_n : out std_logic;
HALT_n : out std_logic;
BUSAK_n : out std_logic;
A : out std_logic_vector(15 downto 0);
DI : in std_logic_vector(7 downto 0);
DO : out std_logic_vector(7 downto 0));
end component;
 
component rom
port (
Clk : in std_logic;
A : in std_logic_vector(15 downto 0);
D : out std_logic_vector(7 downto 0));
end component;
 
component Clock_357Mhz
PORT (
clock_50Mhz : IN STD_LOGIC;
clock_357Mhz : OUT STD_LOGIC);
end component;
component clk_div
PORT
(
clock_25Mhz : IN STD_LOGIC;
clock_1MHz : OUT STD_LOGIC;
clock_100KHz : OUT STD_LOGIC;
clock_10KHz : OUT STD_LOGIC;
clock_1KHz : OUT STD_LOGIC;
clock_100Hz : OUT STD_LOGIC;
clock_10Hz : OUT STD_LOGIC;
clock_1Hz : OUT STD_LOGIC);
end component;
 
component decoder_7seg
port (
NUMBER : in std_logic_vector(3 downto 0);
HEX_DISP : out std_logic_vector(6 downto 0));
end component;
signal MREQ_n : std_logic;
signal IORQ_n : std_logic;
signal RD_n : std_logic;
signal WR_n : std_logic;
signal MWr_n : std_logic;
signal Rst_n_s : std_logic;
signal Clk_Z80 : std_logic;
signal DI_CPU : std_logic_vector(7 downto 0);
signal DO_CPU : std_logic_vector(7 downto 0);
signal A : std_logic_vector(15 downto 0);
signal One : std_logic;
signal D_ROM : std_logic_vector(7 downto 0);
 
signal clk25mhz_sig : std_logic;
signal Clk_1hz : std_logic;
signal HEX_DISP0 : std_logic_vector(6 downto 0);
signal HEX_DISP1 : std_logic_vector(6 downto 0);
signal HEX_DISP2 : std_logic_vector(6 downto 0);
signal HEX_DISP3 : std_logic_vector(6 downto 0);
 
signal NUMBER0 : std_logic_vector(3 downto 0);
signal NUMBER1 : std_logic_vector(3 downto 0);
signal NUMBER2 : std_logic_vector(3 downto 0);
signal NUMBER3 : std_logic_vector(3 downto 0);
signal GPIO_0_buf_in : std_logic_vector(35 downto 0);
signal GPIO_1_buf_in : std_logic_vector(35 downto 0);
 
signal vram_rdaddress_sig : std_logic_vector(12 downto 0);
signal vram_wraddress_sig : std_logic_vector(15 downto 0);
signal vram_data_sig : std_logic_vector(7 downto 0);
signal vram_q_sig : std_logic_vector(7 downto 0);
signal vram_q_reg : std_logic_vector(7 downto 0);
signal vram_wren_sig : std_logic;
signal vram_rden_sig : std_logic;
signal vram_rdcycle_count : std_logic_vector(3 downto 0);
signal vram_wrcycle_count : std_logic_vector(3 downto 0);
signal VRAM_CLOCK : std_logic;
-- PS/2 Keyboard
signal ps2_read : std_logic;
signal ps2_scan_ready : std_logic;
signal ps2_ascii_sig : std_logic_vector(7 downto 0);
signal ps2_ascii_reg1 : std_logic_vector(7 downto 0);
signal ps2_ascii_reg : std_logic_vector(7 downto 0);
begin
HEX0 <= HEX_DISP0;
HEX1 <= HEX_DISP1;
HEX2 <= HEX_DISP2;
HEX3 <= HEX_DISP3;
SRAM_ADDR(15 downto 0) <= A - x"4000" when (A >= x"4000" and MReq_n = '0');
SRAM_DQ(15 downto 8) <= (others => 'Z');
SRAM_ADDR(17 downto 16) <= "00";
SRAM_UB_N <= '1';
SRAM_LB_N <= '0';
SRAM_CE_N <= '0';
SRAM_WE_N <= Wr_n or MReq_n when A >= x"4000";
SRAM_OE_N <= Rd_n;
-- Write to SRAM (0x4000 - 0xFFFF)
SRAM_DQ(7 downto 0) <= DO_CPU when (Wr_n = '0' and MReq_n = '0' and A >= x"4000") else (others => 'Z');
 
-- Write into VRAM
vram_wraddress_sig <= A - x"2000" when (A >= x"2000" and A < x"4000" and MReq_n = '0');
vram_wren_sig <= not Wr_n when (A >= x"2000" and A < x"4000" and IORQ_n = '1');
vram_data_sig <= DO_CPU when (Wr_n = '0' and MReq_n = '0' and A >= x"2000" and A < x"4000") else (others => 'Z');
-- Input to Z80
DI_CPU <= SRAM_DQ(7 downto 0) when (Rd_n = '0' and MReq_n = '0' and A >= x"4000") else
-- vram_q_sig when (A >= x"2000" and A < x"4000") else
D_ROM when (Rd_n = '0' and MReq_n = '0' and A < x"2000") else
SW(7 downto 0) when (IORQ_n = '0' and Rd_n = '0' and A(7 downto 0) = x"20") else
("0000" & KEY) when (IORQ_n = '0' and Rd_n = '0' and A(7 downto 0) = x"30") else
GPIO_0(7 downto 0) when (IORQ_n = '0' and Rd_n = '0' and A(7 downto 0) = x"A0") else
GPIO_0(15 downto 8) when (IORQ_n = '0' and Rd_n = '0' and A(7 downto 0) = x"A1") else
GPIO_0(23 downto 16) when (IORQ_n = '0' and Rd_n = '0' and A(7 downto 0) = x"A2") else
GPIO_0(31 downto 24) when (IORQ_n = '0' and Rd_n = '0' and A(7 downto 0) = x"A3") else
("0000" & GPIO_0(35 downto 32)) when (IORQ_n = '0' and Rd_n = '0' and A(7 downto 0) = x"A4") else
GPIO_1(7 downto 0) when (IORQ_n = '0' and Rd_n = '0' and A(7 downto 0) = x"B0") else
GPIO_1(15 downto 8) when (IORQ_n = '0' and Rd_n = '0' and A(7 downto 0) = x"B1") else
GPIO_1(23 downto 16) when (IORQ_n = '0' and Rd_n = '0' and A(7 downto 0) = x"B2") else
GPIO_1(31 downto 24) when (IORQ_n = '0' and Rd_n = '0' and A(7 downto 0) = x"B3") else
("0000" & GPIO_1(35 downto 32)) when (IORQ_n = '0' and Rd_n = '0' and A(7 downto 0) = x"B4") else
ps2_ascii_reg when (IORQ_n = '0' and Rd_n = '0' and A(7 downto 0) = x"80");
-- Process to latch leds and hex displays
process(Clk_Z80)
variable NUMBER0_sig : std_logic_vector(3 downto 0);
variable NUMBER1_sig : std_logic_vector(3 downto 0);
variable NUMBER2_sig : std_logic_vector(3 downto 0);
variable NUMBER3_sig : std_logic_vector(3 downto 0);
variable LEDG_sig : std_logic_vector(7 downto 0);
variable LEDR_sig : std_logic_vector(9 downto 0);
variable GPIO_0_buf_out: std_logic_vector(35 downto 0);
variable GPIO_1_buf_out: std_logic_vector(35 downto 0);
begin
if Clk_Z80'event and Clk_Z80 = '1' then
if IORQ_n = '0' and Wr_n = '0' then
-- LEDG
if A(7 downto 0) = x"01" then
LEDG_sig := DO_CPU;
-- LEDR
elsif A(7 downto 0) = x"02" then
LEDR_sig(7 downto 0) := DO_CPU;
-- HEX1 and HEX0
elsif A(7 downto 0) = x"10" then
NUMBER0_sig := DO_CPU(3 downto 0);
NUMBER1_sig := DO_CPU(7 downto 4);
-- HEX3 and HEX2
elsif A(7 downto 0) = x"11" then
NUMBER2_sig := DO_CPU(3 downto 0);
NUMBER3_sig := DO_CPU(7 downto 4);
-- GPIO_0
elsif A(7 downto 0) = x"A0" then
GPIO_0_buf_out(7 downto 0) := DO_CPU;
elsif A(7 downto 0) = x"A1" then
GPIO_0_buf_out(15 downto 8) := DO_CPU;
elsif A(7 downto 0) = x"A2" then
GPIO_0_buf_out(23 downto 16) := DO_CPU;
elsif A(7 downto 0) = x"A3" then
GPIO_0_buf_out(31 downto 24) := DO_CPU;
elsif A(7 downto 0) = x"A4" then
GPIO_0_buf_out(35 downto 32) := DO_CPU(3 downto 0);
-- GPIO_1
elsif A(7 downto 0) = x"B0" then
GPIO_1_buf_out(7 downto 0) := DO_CPU;
elsif A(7 downto 0) = x"B1" then
GPIO_1_buf_out(15 downto 8) := DO_CPU;
elsif A(7 downto 0) = x"B2" then
GPIO_1_buf_out(23 downto 16) := DO_CPU;
elsif A(7 downto 0) = x"B3" then
GPIO_1_buf_out(31 downto 24) := DO_CPU;
elsif A(7 downto 0) = x"B4" then
GPIO_1_buf_out(35 downto 32) := DO_CPU(3 downto 0);
elsif A(7 downto 0) = x"C0" then
GPIO_0 <= GPIO_0_buf_out;
elsif A(7 downto 0) = x"C1" then
GPIO_1 <= GPIO_1_buf_out;
end if;
end if;
end if;
-- Latches the signals
NUMBER0 <= NUMBER0_sig;
NUMBER1 <= NUMBER1_sig;
NUMBER2 <= NUMBER2_sig;
NUMBER3 <= NUMBER3_sig;
LEDR(7 downto 0) <= LEDR_sig(7 downto 0);
LEDG <= LEDG_sig;
end process;
-- the following three processes deals with different clock domain signals
ps2_process1: process(CLOCK_50)
begin
if CLOCK_50'event and CLOCK_50 = '1' then
if ps2_read = '1' then
if ps2_ascii_sig /= x"FF" then
ps2_read <= '0';
ps2_ascii_reg1 <= "00000000";
end if;
elsif ps2_scan_ready = '1' then
if ps2_ascii_sig = x"FF" then
ps2_read <= '1';
else
ps2_ascii_reg1 <= ps2_ascii_sig;
end if;
end if;
end if;
end process;
ps2_process2: process(Clk_Z80)
begin
if Clk_Z80'event and Clk_Z80 = '1' then
ps2_ascii_reg <= ps2_ascii_reg1;
end if;
end process;
One <= '1';
Rst_n_s <= not SW(9);
z80_inst: T80s
port map (
M1_n => open,
MREQ_n => MReq_n,
IORQ_n => IORq_n,
RD_n => Rd_n,
WR_n => Wr_n,
RFSH_n => open,
HALT_n => open,
WAIT_n => One,
INT_n => One,
NMI_n => One,
RESET_n => Rst_n_s,
BUSRQ_n => One,
BUSAK_n => open,
CLK_n => Clk_Z80,
A => A,
DI => DI_CPU,
DO => DO_CPU
);
 
vga80x40_inst: work.video_80x40 port map (
CLOCK_50 => CLOCK_50,
VRAM_DATA => vram_q_sig,
VRAM_ADDR => vram_rdaddress_sig,
VRAM_CLOCK => VRAM_CLOCK,
VRAM_WREN => vram_rden_sig,
VGA_R => VGA_R,
VGA_G => VGA_G,
VGA_B => VGA_B,
VGA_HS => VGA_HS,
VGA_VS => VGA_VS
);
 
vram8k_inst : work.vram8k PORT MAP (
rdaddress => vram_rdaddress_sig,
rdclock => not VRAM_CLOCK,
rden => vram_rden_sig,
q => vram_q_sig,
wraddress => vram_wraddress_sig(12 downto 0),
wrclock => Clk_Z80,
wren => vram_wren_sig,
data => vram_data_sig
);
rom_inst: rom
port map (
Clk => Clk_Z80,
A => A,
D => D_ROM
);
clock_z80_inst : Clock_357Mhz
port map (
clock_50Mhz => CLOCK_50,
clock_357Mhz => Clk_Z80
);
 
DISPHEX0 : decoder_7seg PORT MAP (
NUMBER => NUMBER0,
HEX_DISP => HEX_DISP0
);
 
DISPHEX1 : decoder_7seg PORT MAP (
NUMBER => NUMBER1,
HEX_DISP => HEX_DISP1
);
 
DISPHEX2 : decoder_7seg PORT MAP (
NUMBER => NUMBER2,
HEX_DISP => HEX_DISP2
);
 
DISPHEX3 : decoder_7seg PORT MAP (
NUMBER => NUMBER3,
HEX_DISP => HEX_DISP3
);
 
ps2_kbd_inst : work.ps2kbd PORT MAP (
keyboard_clk => PS2_CLK,
keyboard_data => PS2_DAT,
clock => CLOCK_50,
reset => Rst_n_s,
read => ps2_read,
scan_ready => ps2_scan_ready,
ps2_ascii_code => ps2_ascii_sig
);
UART_TXD <= 'Z';
DRAM_ADDR <= (others => '0');
DRAM_LDQM <= '0';
DRAM_UDQM <= '0';
DRAM_WE_N <= '1';
DRAM_CAS_N <= '1';
DRAM_RAS_N <= '1';
DRAM_CS_N <= '1';
DRAM_BA_0 <= '0';
DRAM_BA_1 <= '0';
DRAM_CLK <= '0';
DRAM_CKE <= '0';
FL_ADDR <= (others => '0');
FL_WE_N <= '1';
FL_RST_N <= '0';
FL_OE_N <= '1';
FL_CE_N <= '1';
TDO <= '0';
I2C_SCLK <= '0';
AUD_DACDAT <= '0';
AUD_XCK <= '0';
-- Set all bidirectional ports to tri-state
DRAM_DQ <= (others => 'Z');
FL_DQ <= (others => 'Z');
I2C_SDAT <= 'Z';
AUD_ADCLRCK <= 'Z';
AUD_DACLRCK <= 'Z';
AUD_BCLK <= 'Z';
GPIO_0 <= (others => 'Z');
GPIO_1 <= (others => 'Z');
end;
/VHDL/clock_357mhz.vhd
0,0 → 1,37
-- 3.57 Mhz clock from a 50 Mhz input
-- Ronivon C. costa
-- 03/2008
------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_ARITH.all;
use IEEE.STD_LOGIC_UNSIGNED.all;
 
ENTITY Clock_357Mhz IS
PORT (
clock_50Mhz : IN STD_LOGIC;
clock_357Mhz : OUT STD_LOGIC);
END Clock_357Mhz;
 
ARCHITECTURE rtl OF Clock_357Mhz IS
 
SIGNAL counter: STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL clock_357Mhz_int : STD_LOGIC;
 
BEGIN
 
PROCESS (clock_50Mhz)
BEGIN
IF clock_50Mhz'EVENT and clock_50Mhz = '1' THEN
IF counter < "1110" THEN
counter <= counter + 1;
ELSE
counter <= "0000";
clock_357Mhz_int <= not clock_357Mhz_int;
END IF;
END IF;
clock_357Mhz <= clock_357Mhz_int;
 
END PROCESS;
END rtl;
/VHDL/vram8k.vhd
0,0 → 1,243
-- megafunction wizard: %RAM: 2-PORT%
-- GENERATION: STANDARD
-- VERSION: WM1.0
-- MODULE: altsyncram
 
-- ============================================================
-- File Name: vram8k.vhd
-- Megafunction Name(s):
-- altsyncram
--
-- Simulation Library Files(s):
-- altera_mf
-- ============================================================
-- ************************************************************
-- THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
--
-- 7.2 Build 175 11/20/2007 SP 1 SJ Web Edition
-- ************************************************************
 
 
--Copyright (C) 1991-2007 Altera Corporation
--Your use of Altera Corporation's design tools, logic functions
--and other software and tools, and its AMPP partner logic
--functions, and any output files from any of the foregoing
--(including device programming or simulation files), and any
--associated documentation or information are expressly subject
--to the terms and conditions of the Altera Program License
--Subscription Agreement, Altera MegaCore Function License
--Agreement, or other applicable license agreement, including,
--without limitation, that your use is for the sole purpose of
--programming logic devices manufactured by Altera and sold by
--Altera or its authorized distributors. Please refer to the
--applicable agreement for further details.
 
 
LIBRARY ieee;
USE ieee.std_logic_1164.all;
 
LIBRARY altera_mf;
USE altera_mf.all;
 
ENTITY vram8k IS
PORT
(
data : IN STD_LOGIC_VECTOR (7 DOWNTO 0);
rdaddress : IN STD_LOGIC_VECTOR (12 DOWNTO 0);
rdclock : IN STD_LOGIC ;
rden : IN STD_LOGIC := '1';
wraddress : IN STD_LOGIC_VECTOR (12 DOWNTO 0);
wrclock : IN STD_LOGIC ;
wren : IN STD_LOGIC := '1';
q : OUT STD_LOGIC_VECTOR (7 DOWNTO 0)
);
END vram8k;
 
 
ARCHITECTURE SYN OF vram8k IS
 
SIGNAL sub_wire0 : STD_LOGIC_VECTOR (7 DOWNTO 0);
 
 
 
COMPONENT altsyncram
GENERIC (
address_reg_b : STRING;
clock_enable_input_a : STRING;
clock_enable_input_b : STRING;
clock_enable_output_a : STRING;
clock_enable_output_b : STRING;
intended_device_family : STRING;
lpm_type : STRING;
numwords_a : NATURAL;
numwords_b : NATURAL;
operation_mode : STRING;
outdata_aclr_b : STRING;
outdata_reg_b : STRING;
power_up_uninitialized : STRING;
rdcontrol_reg_b : STRING;
widthad_a : NATURAL;
widthad_b : NATURAL;
width_a : NATURAL;
width_b : NATURAL;
width_byteena_a : NATURAL
);
PORT (
wren_a : IN STD_LOGIC ;
clock0 : IN STD_LOGIC ;
clock1 : IN STD_LOGIC ;
address_a : IN STD_LOGIC_VECTOR (12 DOWNTO 0);
address_b : IN STD_LOGIC_VECTOR (12 DOWNTO 0);
rden_b : IN STD_LOGIC ;
q_b : OUT STD_LOGIC_VECTOR (7 DOWNTO 0);
data_a : IN STD_LOGIC_VECTOR (7 DOWNTO 0)
);
END COMPONENT;
 
BEGIN
q <= sub_wire0(7 DOWNTO 0);
 
altsyncram_component : altsyncram
GENERIC MAP (
address_reg_b => "CLOCK1",
clock_enable_input_a => "BYPASS",
clock_enable_input_b => "BYPASS",
clock_enable_output_a => "BYPASS",
clock_enable_output_b => "BYPASS",
intended_device_family => "Cyclone II",
lpm_type => "altsyncram",
numwords_a => 8192,
numwords_b => 8192,
operation_mode => "DUAL_PORT",
outdata_aclr_b => "NONE",
outdata_reg_b => "UNREGISTERED",
power_up_uninitialized => "FALSE",
rdcontrol_reg_b => "CLOCK1",
widthad_a => 13,
widthad_b => 13,
width_a => 8,
width_b => 8,
width_byteena_a => 1
)
PORT MAP (
wren_a => wren,
clock0 => wrclock,
clock1 => rdclock,
address_a => wraddress,
address_b => rdaddress,
rden_b => rden,
data_a => data,
q_b => sub_wire0
);
 
 
 
END SYN;
 
-- ============================================================
-- CNX file retrieval info
-- ============================================================
-- Retrieval info: PRIVATE: ADDRESSSTALL_A NUMERIC "0"
-- Retrieval info: PRIVATE: ADDRESSSTALL_B NUMERIC "0"
-- Retrieval info: PRIVATE: BYTEENA_ACLR_A NUMERIC "0"
-- Retrieval info: PRIVATE: BYTEENA_ACLR_B NUMERIC "0"
-- Retrieval info: PRIVATE: BYTE_ENABLE_A NUMERIC "0"
-- Retrieval info: PRIVATE: BYTE_ENABLE_B NUMERIC "0"
-- Retrieval info: PRIVATE: BYTE_SIZE NUMERIC "8"
-- Retrieval info: PRIVATE: BlankMemory NUMERIC "1"
-- Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_A NUMERIC "0"
-- Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_B NUMERIC "0"
-- Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_A NUMERIC "0"
-- Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_B NUMERIC "0"
-- Retrieval info: PRIVATE: CLRdata NUMERIC "0"
-- Retrieval info: PRIVATE: CLRq NUMERIC "0"
-- Retrieval info: PRIVATE: CLRrdaddress NUMERIC "0"
-- Retrieval info: PRIVATE: CLRrren NUMERIC "0"
-- Retrieval info: PRIVATE: CLRwraddress NUMERIC "0"
-- Retrieval info: PRIVATE: CLRwren NUMERIC "0"
-- Retrieval info: PRIVATE: Clock NUMERIC "1"
-- Retrieval info: PRIVATE: Clock_A NUMERIC "0"
-- Retrieval info: PRIVATE: Clock_B NUMERIC "0"
-- Retrieval info: PRIVATE: ECC NUMERIC "0"
-- Retrieval info: PRIVATE: IMPLEMENT_IN_LES NUMERIC "0"
-- Retrieval info: PRIVATE: INDATA_ACLR_B NUMERIC "0"
-- Retrieval info: PRIVATE: INDATA_REG_B NUMERIC "0"
-- Retrieval info: PRIVATE: INIT_FILE_LAYOUT STRING "PORT_B"
-- Retrieval info: PRIVATE: INIT_TO_SIM_X NUMERIC "0"
-- Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone II"
-- Retrieval info: PRIVATE: JTAG_ENABLED NUMERIC "0"
-- Retrieval info: PRIVATE: JTAG_ID STRING "NONE"
-- Retrieval info: PRIVATE: MAXIMUM_DEPTH NUMERIC "0"
-- Retrieval info: PRIVATE: MEMSIZE NUMERIC "65536"
-- Retrieval info: PRIVATE: MEM_IN_BITS NUMERIC "0"
-- Retrieval info: PRIVATE: MIFfilename STRING ""
-- Retrieval info: PRIVATE: OPERATION_MODE NUMERIC "2"
-- Retrieval info: PRIVATE: OUTDATA_ACLR_B NUMERIC "0"
-- Retrieval info: PRIVATE: OUTDATA_REG_B NUMERIC "0"
-- Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0"
-- Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_MIXED_PORTS NUMERIC "2"
-- Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_A NUMERIC "3"
-- Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_B NUMERIC "3"
-- Retrieval info: PRIVATE: REGdata NUMERIC "1"
-- Retrieval info: PRIVATE: REGq NUMERIC "1"
-- Retrieval info: PRIVATE: REGrdaddress NUMERIC "1"
-- Retrieval info: PRIVATE: REGrren NUMERIC "1"
-- Retrieval info: PRIVATE: REGwraddress NUMERIC "1"
-- Retrieval info: PRIVATE: REGwren NUMERIC "1"
-- Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
-- Retrieval info: PRIVATE: USE_DIFF_CLKEN NUMERIC "0"
-- Retrieval info: PRIVATE: UseDPRAM NUMERIC "1"
-- Retrieval info: PRIVATE: VarWidth NUMERIC "0"
-- Retrieval info: PRIVATE: WIDTH_READ_A NUMERIC "8"
-- Retrieval info: PRIVATE: WIDTH_READ_B NUMERIC "8"
-- Retrieval info: PRIVATE: WIDTH_WRITE_A NUMERIC "8"
-- Retrieval info: PRIVATE: WIDTH_WRITE_B NUMERIC "8"
-- Retrieval info: PRIVATE: WRADDR_ACLR_B NUMERIC "0"
-- Retrieval info: PRIVATE: WRADDR_REG_B NUMERIC "0"
-- Retrieval info: PRIVATE: WRCTRL_ACLR_B NUMERIC "0"
-- Retrieval info: PRIVATE: enable NUMERIC "0"
-- Retrieval info: PRIVATE: rden NUMERIC "1"
-- Retrieval info: CONSTANT: ADDRESS_REG_B STRING "CLOCK1"
-- Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_A STRING "BYPASS"
-- Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_B STRING "BYPASS"
-- Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_A STRING "BYPASS"
-- Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_B STRING "BYPASS"
-- Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone II"
-- Retrieval info: CONSTANT: LPM_TYPE STRING "altsyncram"
-- Retrieval info: CONSTANT: NUMWORDS_A NUMERIC "8192"
-- Retrieval info: CONSTANT: NUMWORDS_B NUMERIC "8192"
-- Retrieval info: CONSTANT: OPERATION_MODE STRING "DUAL_PORT"
-- Retrieval info: CONSTANT: OUTDATA_ACLR_B STRING "NONE"
-- Retrieval info: CONSTANT: OUTDATA_REG_B STRING "UNREGISTERED"
-- Retrieval info: CONSTANT: POWER_UP_UNINITIALIZED STRING "FALSE"
-- Retrieval info: CONSTANT: RDCONTROL_REG_B STRING "CLOCK1"
-- Retrieval info: CONSTANT: WIDTHAD_A NUMERIC "13"
-- Retrieval info: CONSTANT: WIDTHAD_B NUMERIC "13"
-- Retrieval info: CONSTANT: WIDTH_A NUMERIC "8"
-- Retrieval info: CONSTANT: WIDTH_B NUMERIC "8"
-- Retrieval info: CONSTANT: WIDTH_BYTEENA_A NUMERIC "1"
-- Retrieval info: USED_PORT: data 0 0 8 0 INPUT NODEFVAL data[7..0]
-- Retrieval info: USED_PORT: q 0 0 8 0 OUTPUT NODEFVAL q[7..0]
-- Retrieval info: USED_PORT: rdaddress 0 0 13 0 INPUT NODEFVAL rdaddress[12..0]
-- Retrieval info: USED_PORT: rdclock 0 0 0 0 INPUT NODEFVAL rdclock
-- Retrieval info: USED_PORT: rden 0 0 0 0 INPUT VCC rden
-- Retrieval info: USED_PORT: wraddress 0 0 13 0 INPUT NODEFVAL wraddress[12..0]
-- Retrieval info: USED_PORT: wrclock 0 0 0 0 INPUT NODEFVAL wrclock
-- Retrieval info: USED_PORT: wren 0 0 0 0 INPUT VCC wren
-- Retrieval info: CONNECT: @data_a 0 0 8 0 data 0 0 8 0
-- Retrieval info: CONNECT: @wren_a 0 0 0 0 wren 0 0 0 0
-- Retrieval info: CONNECT: q 0 0 8 0 @q_b 0 0 8 0
-- Retrieval info: CONNECT: @address_a 0 0 13 0 wraddress 0 0 13 0
-- Retrieval info: CONNECT: @address_b 0 0 13 0 rdaddress 0 0 13 0
-- Retrieval info: CONNECT: @rden_b 0 0 0 0 rden 0 0 0 0
-- Retrieval info: CONNECT: @clock0 0 0 0 0 wrclock 0 0 0 0
-- Retrieval info: CONNECT: @clock1 0 0 0 0 rdclock 0 0 0 0
-- Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
-- Retrieval info: GEN_FILE: TYPE_NORMAL vram8k.vhd TRUE
-- Retrieval info: GEN_FILE: TYPE_NORMAL vram8k.inc FALSE
-- Retrieval info: GEN_FILE: TYPE_NORMAL vram8k.cmp TRUE
-- Retrieval info: GEN_FILE: TYPE_NORMAL vram8k.bsf TRUE
-- Retrieval info: GEN_FILE: TYPE_NORMAL vram8k_inst.vhd TRUE
-- Retrieval info: GEN_FILE: TYPE_NORMAL vram8k_waveforms.html TRUE
-- Retrieval info: GEN_FILE: TYPE_NORMAL vram8k_wave*.jpg FALSE
-- Retrieval info: LIB_FILE: altera_mf
/VHDL/vga_sync.vhd
0,0 → 1,333
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_ARITH.all;
use IEEE.STD_LOGIC_UNSIGNED.all;
-- Module Generates Video Sync Signals for Video Montor Interface
-- RGB and Sync outputs tie directly to monitor conector pins
ENTITY VGA_SYNC IS
PORT( clock_50Mhz : IN STD_LOGIC;
red, green, blue : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
red_out, green_out, blue_out : OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
horiz_sync_out, vert_sync_out,
video_on, pixel_clock : OUT STD_LOGIC;
pixel_row, pixel_column : OUT STD_LOGIC_VECTOR(9 DOWNTO 0));
END VGA_SYNC;
ARCHITECTURE a OF VGA_SYNC IS
SIGNAL horiz_sync, vert_sync, pixel_clock_int : STD_LOGIC;
SIGNAL video_on_int, video_on_v, video_on_h : STD_LOGIC;
SIGNAL h_count, v_count :STD_LOGIC_VECTOR(9 DOWNTO 0);
--
-- To select a different screen resolution, clock rate, and refresh rate
-- pick a set of new video timing constant values from table at end of code section
-- enter eight new sync timing constants below and
-- adjust PLL frequency output to pixel clock rate from table
-- using MegaWizard to edit video_PLL.vhd
-- Horizontal Timing Constants
CONSTANT H_pixels_across: Natural := 640;
CONSTANT H_sync_low: Natural := 664;
CONSTANT H_sync_high: Natural := 760;
CONSTANT H_end_count: Natural := 800;
-- Vertical Timing Constants
CONSTANT V_pixels_down: Natural := 480;
CONSTANT V_sync_low: Natural := 491;
CONSTANT V_sync_high: Natural := 493;
CONSTANT V_end_count: Natural := 525;
COMPONENT video_PLL
PORT
(
inclk0 : IN STD_LOGIC := '0';
c0 : OUT STD_LOGIC
);
end component;
 
BEGIN
 
-- PLL below is used to generate the pixel clock frequency
-- Uses DE1 50Mhz clock for PLL's input clock
video_PLL_inst : video_PLL PORT MAP (
inclk0 => Clock_50Mhz,
c0 => pixel_clock_int
);
 
-- video_on is high only when RGB pixel data is being displayed
-- used to blank color signals at screen edges during retrace
video_on_int <= video_on_H AND video_on_V;
-- output pixel clock and video on for external user logic
pixel_clock <= pixel_clock_int;
video_on <= video_on_int;
 
PROCESS
BEGIN
WAIT UNTIL(pixel_clock_int'EVENT) AND (pixel_clock_int='1');
 
--Generate Horizontal and Vertical Timing Signals for Video Signal
-- H_count counts pixels (#pixels across + extra time for sync signals)
--
-- Horiz_sync ------------------------------------__________--------
-- H_count 0 #pixels sync low end
--
IF (h_count = H_end_count) THEN
h_count <= "0000000000";
ELSE
h_count <= h_count + 1;
END IF;
 
--Generate Horizontal Sync Signal using H_count
IF (h_count <= H_sync_high) AND (h_count >= H_sync_low) THEN
horiz_sync <= '0';
ELSE
horiz_sync <= '1';
END IF;
 
--V_count counts rows of pixels (#pixel rows down + extra time for V sync signal)
--
-- Vert_sync -----------------------------------------------_______------------
-- V_count 0 last pixel row V sync low end
--
IF (v_count >= V_end_count) AND (h_count >= H_sync_low) THEN
v_count <= "0000000000";
ELSIF (h_count = H_sync_low) THEN
v_count <= v_count + 1;
END IF;
 
-- Generate Vertical Sync Signal using V_count
IF (v_count <= V_sync_high) AND (v_count >= V_sync_low) THEN
vert_sync <= '0';
ELSE
vert_sync <= '1';
END IF;
 
-- Generate Video on Screen Signals for Pixel Data
-- Video on = 1 indicates pixel are being displayed
-- Video on = 0 retrace - user logic can update pixel
-- memory without needing to read memory for display
IF (h_count < H_pixels_across) THEN
video_on_h <= '1';
pixel_column <= h_count;
ELSE
video_on_h <= '0';
END IF;
 
IF (v_count <= V_pixels_down) THEN
video_on_v <= '1';
pixel_row <= v_count;
ELSE
video_on_v <= '0';
END IF;
 
-- Put all video signals through DFFs to elminate any small timing delays that cause a blurry image
horiz_sync_out <= horiz_sync;
vert_sync_out <= vert_sync;
red_out <= red AND video_on_int & video_on_int & video_on_int & video_on_int;
green_out <= green AND video_on_int & video_on_int & video_on_int & video_on_int;
blue_out <= blue AND video_on_int & video_on_int & video_on_int & video_on_int;
 
END PROCESS;
END a;
--
-- Common Video Modes - pixel clock and sync counter values
--
-- Mode Refresh Hor. Sync Pixel clock Interlaced? VESA?
-- ------------------------------------------------------------
-- 640x480 60Hz 31.5khz 25.175Mhz No No
-- 640x480 63Hz 32.8khz 28.322Mhz No No
-- 640x480 70Hz 36.5khz 31.5Mhz No No
-- 640x480 72Hz 37.9khz 31.5Mhz No Yes
-- 800x600 56Hz 35.1khz 36.0Mhz No Yes
-- 800x600 56Hz 35.4khz 36.0Mhz No No
-- 800x600 60Hz 37.9khz 40.0Mhz No Yes
-- 800x600 60Hz 37.9khz 40.0Mhz No No
-- 800x600 72Hz 48.0khz 50.0Mhz No Yes
-- 1024x768 60Hz 48.4khz 65.0Mhz No Yes
-- 1024x768 60Hz 48.4khz 62.0Mhz No No
-- 1024x768 70Hz 56.5khz 75.0Mhz No Yes
-- 1024x768 70Hz 56.25khz 72.0Mhz No No
-- 1024x768 76Hz 62.5khz 85.0Mhz No No
-- 1280x1024 59Hz 63.6khz 110.0Mhz No No
-- 1280x1024 61Hz 64.24khz 110.0Mhz No No
-- 1280x1024 74Hz 78.85khz 135.0Mhz No No
--
-- Pixel clock within 5% works on most monitors.
-- Faster clocks produce higher refresh rates at the same resolution on
-- most new monitors up to the maximum rate.
-- Some older monitors may not support higher refresh rates
-- or may only sync at specific refresh rates - VESA modes most common.
-- Pixel clock within 5% works on most old monitors.
-- Refresh rates below 60Hz will have some flicker.
-- Bad values such as very high refresh rates may damage some monitors
-- that do not support faster refreseh rates - check monitor specs.
--
-- Small adjustments to the sync low count ranges can be used to move
-- video image left, right (H), down or up (V) on the monitor
--
--
-- 640x480@60Hz Non-Interlaced mode
-- Horizontal Sync = 31.5kHz
-- Timing: H=(0.95us, 3.81us, 1.59us), V=(0.35ms, 0.064ms, 1.02ms)
--
-- clock horizontal timing vertical timing flags
-- Mhz pix.col low high end pix.rows low high end
--640x480 25.175 640 664 760 800 480 491 493 525
-- <-> <->
-- sync pulses: Horiz----------___------ Vert-----------___-------
--
-- Alternate 640x480@60Hz Non-Interlaced mode
-- Horizontal Sync = 31.5kHz
-- Timing: H=(1.27us, 3.81us, 1.27us) V=(0.32ms, 0.06ms, 1.05ms)
--
-- name clock horizontal timing vertical timing flags
--640x480 25.175 640 672 768 800 480 490 492 525
--
--
-- 640x480@63Hz Non-Interlaced mode (non-standard)
-- Horizontal Sync = 32.8kHz
-- Timing: H=(1.41us, 1.41us, 5.08us) V=(0.24ms, 0.092ms, 0.92ms)
--
-- name clock horizontal timing vertical timing flags
--640x480 28.322 640 680 720 864 480 488 491 521
--
--
-- 640x480@70Hz Non-Interlaced mode (non-standard)
-- Horizontal Sync = 36.5kHz
-- Timing: H=(1.27us, 1.27us, 4.57us) V=(0.22ms, 0.082ms, 0.82ms)
--
-- name clock horizontal timing vertical timing flags
--640x480 31.5 640 680 720 864 480 488 491 521
--
--
-- VESA 640x480@72Hz Non-Interlaced mode
-- Horizontal Sync = 37.9kHz
-- Timing: H=(0.76us, 1.27us, 4.06us) V=(0.24ms, 0.079ms, 0.74ms)
--
-- name clock horizontal timing vertical timing flags
--640x480 31.5 640 664 704 832 480 489 492 520
--
--
-- VESA 800x600@56Hz Non-Interlaced mode
-- Horizontal Sync = 35.1kHz
-- Timing: H=(0.67us, 2.00us, 3.56us) V=(0.03ms, 0.063ms, 0.70ms)
--
-- name clock horizontal timing vertical timing flags
--800x600 36 800 824 896 1024 600 601 603 625
--
--
-- Alternate 800x600@56Hz Non-Interlaced mode
-- Horizontal Sync = 35.4kHz
-- Timing: H=(0.89us, 4.00us, 1.11us) V=(0.11ms, 0.057ms, 0.79ms)
--
-- name clock horizontal timing vertical timing flags
--800x600 36 800 832 976 1016 600 604 606 634
--
--
-- VESA 800x600@60Hz Non-Interlaced mode
-- Horizontal Sync = 37.9kHz
-- Timing: H=(1.00us, 3.20us, 2.20us) V=(0.03ms, 0.106ms, 0.61ms)
--
-- name clock horizontal timing vertical timing flags
--800x600 40 800 840 968 1056 600 601 605 628 +hsync +vsync
--
--
-- Alternate 800x600@60Hz Non-Interlaced mode
-- Horizontal Sync = 37.9kHz
-- Timing: H=(1.20us, 3.80us, 1.40us) V=(0.13ms, 0.053ms, 0.69ms)
--
-- name clock horizontal timing vertical timing flags
--800x600 40 800 848 1000 1056 600 605 607 633
--
--
-- VESA 800x600@72Hz Non-Interlaced mode
-- Horizontal Sync = 48kHz
-- Timing: H=(1.12us, 2.40us, 1.28us) V=(0.77ms, 0.13ms, 0.48ms)
--
-- name clock horizontal timing vertical timing flags
--800x600 50 800 856 976 1040 600 637 643 666 +hsync +vsync
--
--
-- VESA 1024x768@60Hz Non-Interlaced mode
-- Horizontal Sync = 48.4kHz
-- Timing: H=(0.12us, 2.22us, 2.58us) V=(0.06ms, 0.12ms, 0.60ms)
--
-- name clock horizontal timing vertical timing flags
--1024x768 65 1024 1032 1176 1344 768 771 777 806 -hsync -vsync
--
--
-- 1024x768@60Hz Non-Interlaced mode (non-standard dot-clock)
-- Horizontal Sync = 48.4kHz
-- Timing: H=(0.65us, 2.84us, 0.65us) V=(0.12ms, 0.041ms, 0.66ms)
--
-- name clock horizontal timing vertical timing flags
--1024x768 62 1024 1064 1240 1280 768 774 776 808
--
--
-- VESA 1024x768@70Hz Non-Interlaced mode
-- Horizontal Sync=56.5kHz
-- Timing: H=(0.32us, 1.81us, 1.92us) V=(0.05ms, 0.14ms, 0.51ms)
--
-- name clock horizontal timing vertical timing flags
--1024x768 75 1024 1048 1184 1328 768 771 777 806 -hsync -vsync
--
--
-- 1024x768@70Hz Non-Interlaced mode (non-standard dot-clock)
-- Horizontal Sync=56.25kHz
-- Timing: H=(0.44us, 1.89us, 1.22us) V=(0.036ms, 0.11ms, 0.53ms)
--
-- name clock horizontal timing vertical timing flags
--1024x768 72 1024 1056 1192 1280 768 770 776 806 -hsync -vsync
--
--
-- 1024x768@76Hz Non-Interlaced mode
-- Horizontal Sync=62.5kHz
-- Timing: H=(0.09us, 1.41us, 2.45us) V=(0.09ms, 0.048ms, 0.62ms)
--
-- name clock horizontal timing vertical timing flags
--1024x768 85 1024 1032 1152 1360 768 784 787 823
--
--
-- 1280x1024@59Hz Non-Interlaced mode (non-standard)
-- Horizontal Sync=63.6kHz
-- Timing: H=(0.36us, 1.45us, 2.25us) V=(0.08ms, 0.11ms, 0.65ms)
--
-- name clock horizontal timing vertical timing flags
--1280x1024 110 1280 1320 1480 1728 1024 1029 1036 1077
--
--
-- 1280x1024@61Hz, Non-Interlaced mode
-- Horizontal Sync=64.25kHz
-- Timing: H=(0.44us, 1.67us, 1.82us) V=(0.02ms, 0.05ms, 0.41ms)
--
-- name clock horizontal timing vertical timing flags
--1280x1024 110 1280 1328 1512 1712 1024 1025 1028 1054
--
--
-- 1280x1024@74Hz, Non-Interlaced mode
-- Horizontal Sync=78.85kHz
-- Timing: H=(0.24us, 1.07us, 1.90us) V=(0.04ms, 0.04ms, 0.43ms)
--
-- name clock horizontal timing vertical timing flags
--1280x1024 135 1280 1312 1456 1712 1024 1027 1030 1064
--
-- VGA female connector: 15 pin small "D" connector
-- _________________________
-- \ 5 4 3 2 1 /
-- \ 10 X 8 7 6 /
-- \ 15 14 13 12 11 /
-- \_________________/
-- Signal Name Pin Number Notes
-- -----------------------------------------------------------------------
-- RED video 1 Analog signal, around 0.7 volt, peak-to-peak 75 ohm
-- GREEN video 2 Analog signal, sround 0.7 volt, peak-to-peak 75 ohm
-- BLUE video 3 Analog signal, around 0.7 volt, peak-to-peak 75 ohm
-- Monitor ID #2 4
-- Digital Ground 5 Ground for the video system.
-- RED ground 6 \ The RGB color video signals each have a separate
-- GREEN ground 7 | ground connection.
-- BLUE ground 8 /
-- KEY 9 (X = Not present)
-- SYNC ground 10 TTL return for the SYNC lines.
-- Monitor ID #0 11
-- Monitor ID #1 12
-- Horizontal Sync 13 Digital levels (0 to 5 volts, TTL output)
-- Vertical Sync 14 Digital levels (0 to 5 volts, TTL output)
-- Not Connected 15 (Not used)
--
/VHDL/decoder_7seg.vhd
0,0 → 1,40
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.all;
USE IEEE.STD_LOGIC_UNSIGNED.all;
 
entity decoder_7seg is
port
(
NUMBER : in std_logic_vector(3 downto 0);
HEX_DISP : out std_logic_vector(6 downto 0)
);
end decoder_7seg;
 
architecture rtl of decoder_7seg is
begin
process(NUMBER)
begin
case NUMBER is
--0 to 9
when "0000" => HEX_DISP <= "1000000";
when "0001" => HEX_DISP <= "1111001";
when "0010" => HEX_DISP <= "0100100";
when "0011" => HEX_DISP <= "0110000";
when "0100" => HEX_DISP <= "0011001";
when "0101" => HEX_DISP <= "0010010";
when "0110" => HEX_DISP <= "0000011";
when "0111" => HEX_DISP <= "1111000";
when "1000" => HEX_DISP <= "0000000";
when "1001" => HEX_DISP <= "0011000";
-- A to F
when "1010" => HEX_DISP <= "0001000";
when "1011" => HEX_DISP <= "0000011";
when "1100" => HEX_DISP <= "1000110";
when "1101" => HEX_DISP <= "0100001";
when "1110" => HEX_DISP <= "0000110";
when "1111" => HEX_DISP <= "0001110";
when others => HEX_DISP <= "1111111";
end case;
end process;
end rtl;
 
/VHDL/t80/T80_RegX.vhd
0,0 → 1,167
--
-- T80 Registers for Xilinx Select RAM
--
-- Version : 0244
--
-- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org)
--
-- All rights reserved
--
-- Redistribution and use in source and synthezised forms, with or without
-- modification, are permitted provided that the following conditions are met:
--
-- Redistributions of source code must retain the above copyright notice,
-- this list of conditions and the following disclaimer.
--
-- Redistributions in synthesized form must reproduce the above copyright
-- notice, this list of conditions and the following disclaimer in the
-- documentation and/or other materials provided with the distribution.
--
-- Neither the name of the author nor the names of other contributors may
-- be used to endorse or promote products derived from this software without
-- specific prior written permission.
--
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-- POSSIBILITY OF SUCH DAMAGE.
--
-- Please report bugs to the author, but before you do so, please
-- make sure that this is not a derivative work and that
-- you have the latest version of this file.
--
-- The latest version of this file can be found at:
-- http://www.opencores.org/cvsweb.shtml/t51/
--
-- Limitations :
--
-- File history :
--
-- 0242 : Initial release
--
-- 0244 : Removed UNISIM library and added componet declaration
--
 
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
 
entity T80_Reg is
port(
Clk : in std_logic;
CEN : in std_logic;
WEH : in std_logic;
WEL : in std_logic;
AddrA : in std_logic_vector(2 downto 0);
AddrB : in std_logic_vector(2 downto 0);
AddrC : in std_logic_vector(2 downto 0);
DIH : in std_logic_vector(7 downto 0);
DIL : in std_logic_vector(7 downto 0);
DOAH : out std_logic_vector(7 downto 0);
DOAL : out std_logic_vector(7 downto 0);
DOBH : out std_logic_vector(7 downto 0);
DOBL : out std_logic_vector(7 downto 0);
DOCH : out std_logic_vector(7 downto 0);
DOCL : out std_logic_vector(7 downto 0)
);
end T80_Reg;
 
architecture rtl of T80_Reg is
 
component RAM16X1D
port(
DPO : out std_ulogic;
SPO : out std_ulogic;
A0 : in std_ulogic;
A1 : in std_ulogic;
A2 : in std_ulogic;
A3 : in std_ulogic;
D : in std_ulogic;
DPRA0 : in std_ulogic;
DPRA1 : in std_ulogic;
DPRA2 : in std_ulogic;
DPRA3 : in std_ulogic;
WCLK : in std_ulogic;
WE : in std_ulogic);
end component;
 
signal ENH : std_logic;
signal ENL : std_logic;
 
begin
 
ENH <= CEN and WEH;
ENL <= CEN and WEL;
 
bG1: for I in 0 to 7 generate
begin
Reg1H : RAM16X1D
port map(
DPO => DOBH(i),
SPO => DOAH(i),
A0 => AddrA(0),
A1 => AddrA(1),
A2 => AddrA(2),
A3 => '0',
D => DIH(i),
DPRA0 => AddrB(0),
DPRA1 => AddrB(1),
DPRA2 => AddrB(2),
DPRA3 => '0',
WCLK => Clk,
WE => ENH);
Reg1L : RAM16X1D
port map(
DPO => DOBL(i),
SPO => DOAL(i),
A0 => AddrA(0),
A1 => AddrA(1),
A2 => AddrA(2),
A3 => '0',
D => DIL(i),
DPRA0 => AddrB(0),
DPRA1 => AddrB(1),
DPRA2 => AddrB(2),
DPRA3 => '0',
WCLK => Clk,
WE => ENL);
Reg2H : RAM16X1D
port map(
DPO => DOCH(i),
SPO => open,
A0 => AddrA(0),
A1 => AddrA(1),
A2 => AddrA(2),
A3 => '0',
D => DIH(i),
DPRA0 => AddrC(0),
DPRA1 => AddrC(1),
DPRA2 => AddrC(2),
DPRA3 => '0',
WCLK => Clk,
WE => ENH);
Reg2L : RAM16X1D
port map(
DPO => DOCL(i),
SPO => open,
A0 => AddrA(0),
A1 => AddrA(1),
A2 => AddrA(2),
A3 => '0',
D => DIL(i),
DPRA0 => AddrC(0),
DPRA1 => AddrC(1),
DPRA2 => AddrC(2),
DPRA3 => '0',
WCLK => Clk,
WE => ENL);
end generate;
 
end;
/VHDL/t80/T80se.vhd
0,0 → 1,184
--
-- Z80 compatible microprocessor core, synchronous top level with clock enable
-- Different timing than the original z80
-- Inputs needs to be synchronous and outputs may glitch
--
-- Version : 0242
--
-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org)
--
-- All rights reserved
--
-- Redistribution and use in source and synthezised forms, with or without
-- modification, are permitted provided that the following conditions are met:
--
-- Redistributions of source code must retain the above copyright notice,
-- this list of conditions and the following disclaimer.
--
-- Redistributions in synthesized form must reproduce the above copyright
-- notice, this list of conditions and the following disclaimer in the
-- documentation and/or other materials provided with the distribution.
--
-- Neither the name of the author nor the names of other contributors may
-- be used to endorse or promote products derived from this software without
-- specific prior written permission.
--
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-- POSSIBILITY OF SUCH DAMAGE.
--
-- Please report bugs to the author, but before you do so, please
-- make sure that this is not a derivative work and that
-- you have the latest version of this file.
--
-- The latest version of this file can be found at:
-- http://www.opencores.org/cvsweb.shtml/t80/
--
-- Limitations :
--
-- File history :
--
-- 0235 : First release
--
-- 0236 : Added T2Write generic
--
-- 0237 : Fixed T2Write with wait state
--
-- 0238 : Updated for T80 interface change
--
-- 0240 : Updated for T80 interface change
--
-- 0242 : Updated for T80 interface change
--
 
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use work.T80_Pack.all;
 
entity T80se is
generic(
Mode : integer := 0; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB
T2Write : integer := 0; -- 0 => WR_n active in T3, /=0 => WR_n active in T2
IOWait : integer := 1 -- 0 => Single cycle I/O, 1 => Std I/O cycle
);
port(
RESET_n : in std_logic;
CLK_n : in std_logic;
CLKEN : in std_logic;
WAIT_n : in std_logic;
INT_n : in std_logic;
NMI_n : in std_logic;
BUSRQ_n : in std_logic;
M1_n : out std_logic;
MREQ_n : out std_logic;
IORQ_n : out std_logic;
RD_n : out std_logic;
WR_n : out std_logic;
RFSH_n : out std_logic;
HALT_n : out std_logic;
BUSAK_n : out std_logic;
A : out std_logic_vector(15 downto 0);
DI : in std_logic_vector(7 downto 0);
DO : out std_logic_vector(7 downto 0)
);
end T80se;
 
architecture rtl of T80se is
 
signal IntCycle_n : std_logic;
signal NoRead : std_logic;
signal Write : std_logic;
signal IORQ : std_logic;
signal DI_Reg : std_logic_vector(7 downto 0);
signal MCycle : std_logic_vector(2 downto 0);
signal TState : std_logic_vector(2 downto 0);
 
begin
 
u0 : T80
generic map(
Mode => Mode,
IOWait => IOWait)
port map(
CEN => CLKEN,
M1_n => M1_n,
IORQ => IORQ,
NoRead => NoRead,
Write => Write,
RFSH_n => RFSH_n,
HALT_n => HALT_n,
WAIT_n => Wait_n,
INT_n => INT_n,
NMI_n => NMI_n,
RESET_n => RESET_n,
BUSRQ_n => BUSRQ_n,
BUSAK_n => BUSAK_n,
CLK_n => CLK_n,
A => A,
DInst => DI,
DI => DI_Reg,
DO => DO,
MC => MCycle,
TS => TState,
IntCycle_n => IntCycle_n);
 
process (RESET_n, CLK_n)
begin
if RESET_n = '0' then
RD_n <= '1';
WR_n <= '1';
IORQ_n <= '1';
MREQ_n <= '1';
DI_Reg <= "00000000";
elsif CLK_n'event and CLK_n = '1' then
if CLKEN = '1' then
RD_n <= '1';
WR_n <= '1';
IORQ_n <= '1';
MREQ_n <= '1';
if MCycle = "001" then
if TState = "001" or (TState = "010" and Wait_n = '0') then
RD_n <= not IntCycle_n;
MREQ_n <= not IntCycle_n;
IORQ_n <= IntCycle_n;
end if;
if TState = "011" then
MREQ_n <= '0';
end if;
else
if (TState = "001" or (TState = "010" and Wait_n = '0')) and NoRead = '0' and Write = '0' then
RD_n <= '0';
IORQ_n <= not IORQ;
MREQ_n <= IORQ;
end if;
if T2Write = 0 then
if TState = "010" and Write = '1' then
WR_n <= '0';
IORQ_n <= not IORQ;
MREQ_n <= IORQ;
end if;
else
if (TState = "001" or (TState = "010" and Wait_n = '0')) and Write = '1' then
WR_n <= '0';
IORQ_n <= not IORQ;
MREQ_n <= IORQ;
end if;
end if;
end if;
if TState = "010" and Wait_n = '1' then
DI_Reg <= DI;
end if;
end if;
end if;
end process;
 
end;
/VHDL/t80/T16450.vhd
0,0 → 1,459
--
-- 16450 compatible UART with synchronous bus interface
-- RClk/BaudOut is XIn enable instead of actual clock
--
-- Version : 0249b
--
-- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org)
--
-- All rights reserved
--
-- Redistribution and use in source and synthezised forms, with or without
-- modification, are permitted provided that the following conditions are met:
--
-- Redistributions of source code must retain the above copyright notice,
-- this list of conditions and the following disclaimer.
--
-- Redistributions in synthesized form must reproduce the above copyright
-- notice, this list of conditions and the following disclaimer in the
-- documentation and/or other materials provided with the distribution.
--
-- Neither the name of the author nor the names of other contributors may
-- be used to endorse or promote products derived from this software without
-- specific prior written permission.
--
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-- POSSIBILITY OF SUCH DAMAGE.
--
-- Please report bugs to the author, but before you do so, please
-- make sure that this is not a derivative work and that
-- you have the latest version of this file.
--
-- The latest version of this file can be found at:
-- http://www.opencores.org/cvsweb.shtml/t80/
--
-- Limitations :
--
-- File history :
--
-- 0208 : First release
--
-- 0249 : Fixed interrupt and baud rate bugs found by Andy Dyer
-- Added modem status and break detection
-- Added support for 1.5 and 2 stop bits
--
-- 0249b : Fixed loopback break generation bugs found by Andy Dyer
--
 
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
 
entity T16450 is
port(
MR_n : in std_logic;
XIn : in std_logic;
RClk : in std_logic;
CS_n : in std_logic;
Rd_n : in std_logic;
Wr_n : in std_logic;
A : in std_logic_vector(2 downto 0);
D_In : in std_logic_vector(7 downto 0);
D_Out : out std_logic_vector(7 downto 0);
SIn : in std_logic;
CTS_n : in std_logic;
DSR_n : in std_logic;
RI_n : in std_logic;
DCD_n : in std_logic;
SOut : out std_logic;
RTS_n : out std_logic;
DTR_n : out std_logic;
OUT1_n : out std_logic;
OUT2_n : out std_logic;
BaudOut : out std_logic;
Intr : out std_logic
);
end T16450;
 
architecture rtl of T16450 is
 
signal RBR : std_logic_vector(7 downto 0); -- Reciever Buffer Register
signal THR : std_logic_vector(7 downto 0); -- Transmitter Holding Register
signal IER : std_logic_vector(7 downto 0); -- Interrupt Enable Register
signal IIR : std_logic_vector(7 downto 0); -- Interrupt Ident. Register
signal LCR : std_logic_vector(7 downto 0); -- Line Control Register
signal MCR : std_logic_vector(7 downto 0); -- MODEM Control Register
signal LSR : std_logic_vector(7 downto 0); -- Line Status Register
signal MSR : std_logic_vector(7 downto 0); -- MODEM Status Register
signal SCR : std_logic_vector(7 downto 0); -- Scratch Register
signal DLL : std_logic_vector(7 downto 0); -- Divisor Latch (LS)
signal DLM : std_logic_vector(7 downto 0); -- Divisor Latch (MS)
 
signal DM0 : std_logic_vector(7 downto 0);
signal DM1 : std_logic_vector(7 downto 0);
 
signal MSR_In : std_logic_vector(3 downto 0);
 
signal Bit_Phase : unsigned(3 downto 0);
signal Brk_Cnt : unsigned(3 downto 0);
signal RX_Filtered : std_logic;
signal RX_ShiftReg : std_logic_vector(7 downto 0);
signal RX_Bit_Cnt : integer range 0 to 11;
signal RX_Parity : std_logic;
signal RXD : std_logic;
 
signal TX_Tick : std_logic;
signal TX_ShiftReg : std_logic_vector(7 downto 0);
signal TX_Bit_Cnt : integer range 0 to 11;
signal TX_Parity : std_logic;
signal TX_Next_Is_Stop : std_logic;
signal TX_Stop_Bit : std_logic;
signal TXD : std_logic;
 
begin
 
DTR_n <= MCR(4) or not MCR(0);
RTS_n <= MCR(4) or not MCR(1);
OUT1_n <= MCR(4) or not MCR(2);
OUT2_n <= MCR(4) or not MCR(3);
SOut <= MCR(4) or (TXD and not LCR(6));
RXD <= SIn when MCR(4) = '0' else (TXD and not LCR(6));
 
Intr <= not IIR(0);
 
-- Registers
DM0 <= DLL when LCR(7) = '1' else RBR;
DM1 <= DLM when LCR(7) = '1' else IER;
with A select
D_Out <=
DM0 when "000",
DM1 when "001",
IIR when "010",
LCR when "011",
MCR when "100",
LSR when "101",
MSR when "110",
SCR when others;
process (MR_n, XIn)
begin
if MR_n = '0' then
THR <= "00000000";
IER <= "00000000";
LCR <= "00000000";
MCR <= "00000000";
MSR(3 downto 0) <= "0000";
SCR <= "00000000"; -- ??
DLL <= "00000000"; -- ??
DLM <= "00000000"; -- ??
elsif XIn'event and XIn = '1' then
if Wr_n = '0' and CS_n = '0' then
case A is
when "000" =>
if LCR(7) = '1' then
DLL <= D_In;
else
THR <= D_In;
end if;
when "001" =>
if LCR(7) = '1' then
DLM <= D_In;
else
IER(3 downto 0) <= D_In(3 downto 0);
end if;
when "011" =>
LCR <= D_In;
when "100" =>
MCR <= D_In;
when "111" =>
SCR <= D_In;
when others =>
end case;
end if;
if Rd_n = '0' and CS_n = '0' and A = "110" then
MSR(3 downto 0) <= "0000";
end if;
if MSR(4) /= MSR_In(0) then
MSR(0) <= '1';
end if;
if MSR(5) /= MSR_In(1) then
MSR(1) <= '1';
end if;
if MSR(6) = '0' and MSR_In(2) = '1' then
MSR(2) <= '1';
end if;
if MSR(7) /= MSR_In(3) then
MSR(3) <= '1';
end if;
end if;
end process;
process (XIn)
begin
if XIn'event and XIn = '1' then
if MCR(4) = '0' then
MSR(4) <= MSR_In(0);
MSR(5) <= MSR_In(1);
MSR(6) <= MSR_In(2);
MSR(7) <= MSR_In(3);
else
MSR(4) <= MCR(1);
MSR(5) <= MCR(0);
MSR(6) <= MCR(2);
MSR(7) <= MCR(3);
end if;
MSR_In(0) <= CTS_n;
MSR_In(1) <= DSR_n;
MSR_In(2) <= RI_n;
MSR_In(3) <= DCD_n;
end if;
end process;
 
IIR(7 downto 3) <= "00000";
IIR(2 downto 0) <=
"110" when IER(2) = '1' and LSR(4 downto 1) /= "0000" else
"100" when (IER(0) and LSR(0)) = '1' else
"010" when (IER(1) and LSR(5)) = '1' else
"000" when IER(3) = '1' and ((MCR(4) = '0' and MSR(3 downto 0) /= "0000") or
(MCR(4) = '1' and MCR(3 downto 0) /= "0000")) else
"001";
 
-- Baud x 16 clock generator
process (MR_n, XIn)
variable Baud_Cnt : unsigned(15 downto 0);
begin
if MR_n = '0' then
Baud_Cnt := "0000000000000000";
BaudOut <= '0';
elsif XIn'event and XIn = '1' then
if Baud_Cnt(15 downto 1) = "000000000000000" or (Wr_n = '0' and CS_n = '0' and A(2 downto 1) = "00" and LCR(7) = '1') then
Baud_Cnt(15 downto 8) := unsigned(DLM);
Baud_Cnt(7 downto 0) := unsigned(DLL);
BaudOut <= '1';
else
Baud_Cnt := Baud_Cnt - 1;
BaudOut <= '0';
end if;
end if;
end process;
 
-- Input filter
process (MR_n, XIn)
variable Samples : std_logic_vector(1 downto 0);
begin
if MR_n = '0' then
Samples := "11";
RX_Filtered <= '1';
elsif XIn'event and XIn = '1' then
if RClk = '1' then
Samples(1) := Samples(0);
Samples(0) := RXD;
end if;
if Samples = "00" then
RX_Filtered <= '0';
end if;
if Samples = "11" then
RX_Filtered <= '1';
end if;
end if;
end process;
 
-- Receive state machine
process (MR_n, XIn)
begin
if MR_n = '0' then
RBR <= "00000000";
LSR(4 downto 0) <= "00000";
Bit_Phase <= "0000";
Brk_Cnt <= "0000";
RX_ShiftReg(7 downto 0) <= "00000000";
RX_Bit_Cnt <= 0;
RX_Parity <= '0';
elsif XIn'event and XIn = '1' then
if A = "000" and LCR(7) = '0' and Rd_n = '0' and CS_n = '0' then
LSR(0) <= '0'; -- DR
end if;
if A = "101" and Rd_n = '0' and CS_n = '0' then
LSR(4) <= '0'; -- BI
LSR(3) <= '0'; -- FE
LSR(2) <= '0'; -- PE
LSR(1) <= '0'; -- OE
end if;
if RClk = '1' then
if RX_Bit_Cnt = 0 and (RX_Filtered = '1' or Bit_Phase = "0111") then
Bit_Phase <= "0000";
else
Bit_Phase <= Bit_Phase + 1;
end if;
if Bit_Phase = "1111" then
if RX_Filtered = '1' then
Brk_Cnt <= "0000";
else
Brk_Cnt <= Brk_Cnt + 1;
end if;
if Brk_Cnt = "1100" then
LSR(4) <= '1'; -- BI
end if;
end if;
if RX_Bit_Cnt = 0 then
if Bit_Phase = "0111" then
RX_Bit_Cnt <= RX_Bit_Cnt + 1;
RX_Parity <= not LCR(4); -- EPS
end if;
elsif Bit_Phase = "1111" then
RX_Bit_Cnt <= RX_Bit_Cnt + 1;
if RX_Bit_Cnt = 10 then -- Parity stop bit
RX_Bit_Cnt <= 0;
LSR(0) <= '1'; -- UART Receive complete
LSR(3) <= not RX_Filtered; -- Framing error
elsif (RX_Bit_Cnt = 9 and LCR(1 downto 0) = "11") or
(RX_Bit_Cnt = 8 and LCR(1 downto 0) = "10") or
(RX_Bit_Cnt = 7 and LCR(1 downto 0) = "01") or
(RX_Bit_Cnt = 6 and LCR(1 downto 0) = "00") then -- Stop bit/Parity
RX_Bit_Cnt <= 0;
if LCR(3) = '1' then -- PEN
RX_Bit_Cnt <= 10;
if LCR(5) = '1' then -- Stick parity
if RX_Filtered = LCR(4) then
LSR(2) <= '1';
end if;
else
if RX_Filtered /= RX_Parity then
LSR(2) <= '1';
end if;
end if;
else
LSR(0) <= '1'; -- UART Receive complete
LSR(3) <= not RX_Filtered; -- Framing error
end if;
RBR <= RX_ShiftReg(7 downto 0);
LSR(1) <= LSR(0);
if A = "101" and Rd_n = '0' and CS_n = '0' then
LSR(1) <= '0';
end if;
else
RX_ShiftReg(6 downto 0) <= RX_ShiftReg(7 downto 1);
RX_ShiftReg(7) <= RX_Filtered;
if LCR(1 downto 0) = "10" then
RX_ShiftReg(7) <= '0';
RX_ShiftReg(6) <= RX_Filtered;
end if;
if LCR(1 downto 0) = "01" then
RX_ShiftReg(7) <= '0';
RX_ShiftReg(6) <= '0';
RX_ShiftReg(5) <= RX_Filtered;
end if;
if LCR(1 downto 0) = "00" then
RX_ShiftReg(7) <= '0';
RX_ShiftReg(6) <= '0';
RX_ShiftReg(5) <= '0';
RX_ShiftReg(4) <= RX_Filtered;
end if;
RX_Parity <= RX_Filtered xor RX_Parity;
end if;
end if;
end if;
end if;
end process;
 
-- Transmit bit tick
process (MR_n, XIn)
variable TX_Cnt : unsigned(4 downto 0);
begin
if MR_n = '0' then
TX_Cnt := "00000";
TX_Tick <= '0';
elsif XIn'event and XIn = '1' then
TX_Tick <= '0';
if RClk = '1' then
TX_Cnt := TX_Cnt + 1;
if LCR(2) = '1' and TX_Stop_Bit = '1' then
if LCR(1 downto 0) = "00" then
if TX_Cnt = "10111" then
TX_Tick <= '1';
TX_Cnt(3 downto 0) := "0000";
end if;
else
if TX_Cnt = "11111" then
TX_Tick <= '1';
TX_Cnt(3 downto 0) := "0000";
end if;
end if;
else
TX_Cnt(4) := '1';
if TX_Cnt(3 downto 0) = "1111" then
TX_Tick <= '1';
end if;
end if;
end if;
end if;
end process;
 
-- Transmit state machine
process (MR_n, XIn)
begin
if MR_n = '0' then
LSR(7 downto 5) <= "011";
TX_Bit_Cnt <= 0;
TX_ShiftReg <= (others => '0');
TXD <= '1';
TX_Parity <= '0';
TX_Next_Is_Stop <= '0';
TX_Stop_Bit <= '0';
elsif XIn'event and XIn = '1' then
if TX_Tick = '1' then
TX_Next_Is_Stop <= '0';
TX_Stop_Bit <= TX_Next_Is_Stop;
case TX_Bit_Cnt is
when 0 =>
if LSR(5) <= '0' then -- THRE
TX_Bit_Cnt <= 1;
end if;
TXD <= '1';
when 1 => -- Start bit
TX_ShiftReg(7 downto 0) <= THR;
LSR(5) <= '1'; -- THRE
TXD <= '0';
TX_Parity <= not LCR(4); -- EPS
TX_Bit_Cnt <= TX_Bit_Cnt + 1;
when 10 => -- Parity bit
TXD <= TX_Parity;
if LCR(5) = '1' then -- Stick parity
TXD <= not LCR(4);
end if;
TX_Bit_Cnt <= 0;
TX_Next_Is_Stop <= '1';
when others =>
TX_Bit_Cnt <= TX_Bit_Cnt + 1;
if (TX_Bit_Cnt = 9 and LCR(1 downto 0) = "11") or
(TX_Bit_Cnt = 8 and LCR(1 downto 0) = "10") or
(TX_Bit_Cnt = 7 and LCR(1 downto 0) = "01") or
(TX_Bit_Cnt = 6 and LCR(1 downto 0) = "00") then
TX_Bit_Cnt <= 0;
if LCR(3) = '1' then -- PEN
TX_Bit_Cnt <= 10;
else
TX_Next_Is_Stop <= '1';
end if;
LSR(6) <= '1'; -- TEMT
end if;
TXD <= TX_ShiftReg(0);
TX_ShiftReg(6 downto 0) <= TX_ShiftReg(7 downto 1);
TX_Parity <= TX_ShiftReg(0) xor TX_Parity;
end case;
end if;
if Wr_n = '0' and CS_n = '0' and A = "000" and LCR(7) = '0' then
LSR(5) <= '0'; -- THRE
LSR(6) <= '0'; -- TEMT
end if;
end if;
end process;
 
end;
/VHDL/t80/DebugSystemXR.vhd
0,0 → 1,185
-- Z80, Monitor ROM, external SRAM interface and two 16450 UARTs
-- that can be synthesized and used with
-- the NoICE debugger that can be found at
-- http://www.noicedebugger.com/
 
library IEEE;
use IEEE.std_logic_1164.all;
 
entity DebugSystemXR is
port(
Reset_n : in std_logic;
Clk : in std_logic;
NMI_n : in std_logic;
OE_n : out std_logic;
WE_n : out std_logic;
RAMCS_n : out std_logic;
ROMCS_n : out std_logic;
PGM_n : out std_logic;
A : out std_logic_vector(16 downto 0);
D : inout std_logic_vector(7 downto 0);
RXD0 : in std_logic;
CTS0 : in std_logic;
DSR0 : in std_logic;
RI0 : in std_logic;
DCD0 : in std_logic;
RXD1 : in std_logic;
CTS1 : in std_logic;
DSR1 : in std_logic;
RI1 : in std_logic;
DCD1 : in std_logic;
TXD0 : out std_logic;
RTS0 : out std_logic;
DTR0 : out std_logic;
TXD1 : out std_logic;
RTS1 : out std_logic;
DTR1 : out std_logic
);
end entity DebugSystemXR;
 
architecture struct of DebugSystemXR is
 
signal M1_n : std_logic;
signal MREQ_n : std_logic;
signal IORQ_n : std_logic;
signal RD_n : std_logic;
signal WR_n : std_logic;
signal RFSH_n : std_logic;
signal HALT_n : std_logic;
signal WAIT_n : std_logic;
signal INT_n : std_logic;
signal RESET_s : std_logic;
signal BUSRQ_n : std_logic;
signal BUSAK_n : std_logic;
signal A_i : std_logic_vector(15 downto 0);
signal D_i : std_logic_vector(7 downto 0);
signal ROM_D : std_logic_vector(7 downto 0);
signal UART0_D : std_logic_vector(7 downto 0);
signal UART1_D : std_logic_vector(7 downto 0);
signal CPU_D : std_logic_vector(7 downto 0);
 
signal Mirror : std_logic;
 
signal IOWR_n : std_logic;
signal RAMCS_n_i : std_logic;
signal UART0CS_n : std_logic;
signal UART1CS_n : std_logic;
 
signal BaudOut0 : std_logic;
signal BaudOut1 : std_logic;
 
begin
 
Wait_n <= '1';
BusRq_n <= '1';
INT_n <= '1';
 
OE_n <= RD_n;
WE_n <= WR_n;
RAMCS_n <= RAMCS_n_i;
ROMCS_n <= '1';
PGM_n <= '1';
A(14 downto 0) <= A_i(14 downto 0);
A(16 downto 15) <= "00";
D <= D_i when WR_n = '0' else "ZZZZZZZZ";
 
process (Reset_n, Clk)
begin
if Reset_n = '0' then
Reset_s <= '0';
Mirror <= '0';
elsif Clk'event and Clk = '1' then
Reset_s <= '1';
if IORQ_n = '0' and A_i(7 downto 4) = "1111" then
Mirror <= D_i(0);
end if;
end if;
end process;
 
IOWR_n <= WR_n or IORQ_n;
RAMCS_n_i <= (not Mirror and not A_i(15)) or MREQ_n;
UART0CS_n <= '0' when IORQ_n = '0' and A_i(7 downto 3) = "00000" else '1';
UART1CS_n <= '0' when IORQ_n = '0' and A_i(7 downto 3) = "10000" else '1';
 
CPU_D <=
D when RAMCS_n_i = '0' else
UART0_D when UART0CS_n = '0' else
UART1_D when UART1CS_n = '0' else
ROM_D;
 
u0 : entity work.T80s
generic map(Mode => 1, T2Write => 1, IOWait => 0)
port map(
RESET_n => RESET_s,
CLK_n => Clk,
WAIT_n => WAIT_n,
INT_n => INT_n,
NMI_n => NMI_n,
BUSRQ_n => BUSRQ_n,
M1_n => M1_n,
MREQ_n => MREQ_n,
IORQ_n => IORQ_n,
RD_n => RD_n,
WR_n => WR_n,
RFSH_n => RFSH_n,
HALT_n => HALT_n,
BUSAK_n => BUSAK_n,
A => A_i,
DI => CPU_D,
DO => D_i);
 
u1 : entity work.MonZ80
port map(
Clk => Clk,
A => A_i(10 downto 0),
D => ROM_D);
 
u3 : entity work.T16450
port map(
MR_n => Reset_s,
XIn => Clk,
RClk => BaudOut0,
CS_n => UART0CS_n,
Rd_n => RD_n,
Wr_n => IOWR_n,
A => A_i(2 downto 0),
D_In => D_i,
D_Out => UART0_D,
SIn => RXD0,
CTS_n => CTS0,
DSR_n => DSR0,
RI_n => RI0,
DCD_n => DCD0,
SOut => TXD0,
RTS_n => RTS0,
DTR_n => DTR0,
OUT1_n => open,
OUT2_n => open,
BaudOut => BaudOut0,
Intr => open);
 
u4 : entity work.T16450
port map(
MR_n => Reset_s,
XIn => Clk,
RClk => BaudOut1,
CS_n => UART1CS_n,
Rd_n => RD_n,
Wr_n => IOWR_n,
A => A_i(2 downto 0),
D_In => D_i,
D_Out => UART1_D,
SIn => RXD1,
CTS_n => CTS1,
DSR_n => DSR1,
RI_n => RI1,
DCD_n => DCD1,
SOut => TXD1,
RTS_n => RTS1,
DTR_n => DTR1,
OUT1_n => open,
OUT2_n => open,
BaudOut => BaudOut1,
Intr => open);
 
end;
/VHDL/t80/SSRAM2.vhd
0,0 → 1,92
--
-- Inferrable Synchronous SRAM for Leonardo synthesis, no write through!
--
-- Version : 0236
--
-- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org)
--
-- All rights reserved
--
-- Redistribution and use in source and synthezised forms, with or without
-- modification, are permitted provided that the following conditions are met:
--
-- Redistributions of source code must retain the above copyright notice,
-- this list of conditions and the following disclaimer.
--
-- Redistributions in synthesized form must reproduce the above copyright
-- notice, this list of conditions and the following disclaimer in the
-- documentation and/or other materials provided with the distribution.
--
-- Neither the name of the author nor the names of other contributors may
-- be used to endorse or promote products derived from this software without
-- specific prior written permission.
--
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-- POSSIBILITY OF SUCH DAMAGE.
--
-- Please report bugs to the author, but before you do so, please
-- make sure that this is not a derivative work and that
-- you have the latest version of this file.
--
-- The latest version of this file can be found at:
-- http://www.opencores.org/cvsweb.shtml/t51/
--
-- Limitations :
--
-- File history :
--
 
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
 
entity SSRAM is
generic(
AddrWidth : integer := 16;
DataWidth : integer := 8
);
port(
Clk : in std_logic;
CE_n : in std_logic;
WE_n : in std_logic;
A : in std_logic_vector(AddrWidth - 1 downto 0);
DIn : in std_logic_vector(DataWidth - 1 downto 0);
DOut : out std_logic_vector(DataWidth - 1 downto 0)
);
end SSRAM;
 
architecture behaviour of SSRAM is
 
type Memory_Image is array (natural range <>) of std_logic_vector(DataWidth - 1 downto 0);
signal RAM : Memory_Image(0 to 2 ** AddrWidth - 1);
-- signal A_r : std_logic_vector(AddrWidth - 1 downto 0);
 
begin
 
process (Clk)
begin
if Clk'event and Clk = '1' then
-- pragma translate_off
if not is_x(A) then
-- pragma translate_on
DOut <= RAM(to_integer(unsigned(A(AddrWidth - 1 downto 0))));
-- pragma translate_off
end if;
-- pragma translate_on
if CE_n = '0' and WE_n = '0' then
RAM(to_integer(unsigned(A))) <= DIn;
end if;
-- A_r <= A;
end if;
end process;
 
end;
/VHDL/t80/T80_Reg.vhd
0,0 → 1,105
--
-- T80 Registers, technology independent
--
-- Version : 0244
--
-- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org)
--
-- All rights reserved
--
-- Redistribution and use in source and synthezised forms, with or without
-- modification, are permitted provided that the following conditions are met:
--
-- Redistributions of source code must retain the above copyright notice,
-- this list of conditions and the following disclaimer.
--
-- Redistributions in synthesized form must reproduce the above copyright
-- notice, this list of conditions and the following disclaimer in the
-- documentation and/or other materials provided with the distribution.
--
-- Neither the name of the author nor the names of other contributors may
-- be used to endorse or promote products derived from this software without
-- specific prior written permission.
--
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-- POSSIBILITY OF SUCH DAMAGE.
--
-- Please report bugs to the author, but before you do so, please
-- make sure that this is not a derivative work and that
-- you have the latest version of this file.
--
-- The latest version of this file can be found at:
-- http://www.opencores.org/cvsweb.shtml/t51/
--
-- Limitations :
--
-- File history :
--
-- 0242 : Initial release
--
-- 0244 : Changed to single register file
--
 
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
 
entity T80_Reg is
port(
Clk : in std_logic;
CEN : in std_logic;
WEH : in std_logic;
WEL : in std_logic;
AddrA : in std_logic_vector(2 downto 0);
AddrB : in std_logic_vector(2 downto 0);
AddrC : in std_logic_vector(2 downto 0);
DIH : in std_logic_vector(7 downto 0);
DIL : in std_logic_vector(7 downto 0);
DOAH : out std_logic_vector(7 downto 0);
DOAL : out std_logic_vector(7 downto 0);
DOBH : out std_logic_vector(7 downto 0);
DOBL : out std_logic_vector(7 downto 0);
DOCH : out std_logic_vector(7 downto 0);
DOCL : out std_logic_vector(7 downto 0)
);
end T80_Reg;
 
architecture rtl of T80_Reg is
 
type Register_Image is array (natural range <>) of std_logic_vector(7 downto 0);
signal RegsH : Register_Image(0 to 7);
signal RegsL : Register_Image(0 to 7);
 
begin
 
process (Clk)
begin
if Clk'event and Clk = '1' then
if CEN = '1' then
if WEH = '1' then
RegsH(to_integer(unsigned(AddrA))) <= DIH;
end if;
if WEL = '1' then
RegsL(to_integer(unsigned(AddrA))) <= DIL;
end if;
end if;
end if;
end process;
 
DOAH <= RegsH(to_integer(unsigned(AddrA)));
DOAL <= RegsL(to_integer(unsigned(AddrA)));
DOBH <= RegsH(to_integer(unsigned(AddrB)));
DOBL <= RegsL(to_integer(unsigned(AddrB)));
DOCH <= RegsH(to_integer(unsigned(AddrC)));
DOCL <= RegsL(to_integer(unsigned(AddrC)));
 
end;
/VHDL/t80/T80_Pack.vhd
0,0 → 1,208
--
-- Z80 compatible microprocessor core
--
-- Version : 0242
--
-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org)
--
-- All rights reserved
--
-- Redistribution and use in source and synthezised forms, with or without
-- modification, are permitted provided that the following conditions are met:
--
-- Redistributions of source code must retain the above copyright notice,
-- this list of conditions and the following disclaimer.
--
-- Redistributions in synthesized form must reproduce the above copyright
-- notice, this list of conditions and the following disclaimer in the
-- documentation and/or other materials provided with the distribution.
--
-- Neither the name of the author nor the names of other contributors may
-- be used to endorse or promote products derived from this software without
-- specific prior written permission.
--
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-- POSSIBILITY OF SUCH DAMAGE.
--
-- Please report bugs to the author, but before you do so, please
-- make sure that this is not a derivative work and that
-- you have the latest version of this file.
--
-- The latest version of this file can be found at:
-- http://www.opencores.org/cvsweb.shtml/t80/
--
-- Limitations :
--
-- File history :
--
 
library IEEE;
use IEEE.std_logic_1164.all;
 
package T80_Pack is
 
component T80
generic(
Mode : integer := 0; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB
IOWait : integer := 0; -- 1 => Single cycle I/O, 1 => Std I/O cycle
Flag_C : integer := 0;
Flag_N : integer := 1;
Flag_P : integer := 2;
Flag_X : integer := 3;
Flag_H : integer := 4;
Flag_Y : integer := 5;
Flag_Z : integer := 6;
Flag_S : integer := 7
);
port(
RESET_n : in std_logic;
CLK_n : in std_logic;
CEN : in std_logic;
WAIT_n : in std_logic;
INT_n : in std_logic;
NMI_n : in std_logic;
BUSRQ_n : in std_logic;
M1_n : out std_logic;
IORQ : out std_logic;
NoRead : out std_logic;
Write : out std_logic;
RFSH_n : out std_logic;
HALT_n : out std_logic;
BUSAK_n : out std_logic;
A : out std_logic_vector(15 downto 0);
DInst : in std_logic_vector(7 downto 0);
DI : in std_logic_vector(7 downto 0);
DO : out std_logic_vector(7 downto 0);
MC : out std_logic_vector(2 downto 0);
TS : out std_logic_vector(2 downto 0);
IntCycle_n : out std_logic;
IntE : out std_logic;
Stop : out std_logic
);
end component;
 
component T80_Reg
port(
Clk : in std_logic;
CEN : in std_logic;
WEH : in std_logic;
WEL : in std_logic;
AddrA : in std_logic_vector(2 downto 0);
AddrB : in std_logic_vector(2 downto 0);
AddrC : in std_logic_vector(2 downto 0);
DIH : in std_logic_vector(7 downto 0);
DIL : in std_logic_vector(7 downto 0);
DOAH : out std_logic_vector(7 downto 0);
DOAL : out std_logic_vector(7 downto 0);
DOBH : out std_logic_vector(7 downto 0);
DOBL : out std_logic_vector(7 downto 0);
DOCH : out std_logic_vector(7 downto 0);
DOCL : out std_logic_vector(7 downto 0)
);
end component;
 
component T80_MCode
generic(
Mode : integer := 0;
Flag_C : integer := 0;
Flag_N : integer := 1;
Flag_P : integer := 2;
Flag_X : integer := 3;
Flag_H : integer := 4;
Flag_Y : integer := 5;
Flag_Z : integer := 6;
Flag_S : integer := 7
);
port(
IR : in std_logic_vector(7 downto 0);
ISet : in std_logic_vector(1 downto 0);
MCycle : in std_logic_vector(2 downto 0);
F : in std_logic_vector(7 downto 0);
NMICycle : in std_logic;
IntCycle : in std_logic;
MCycles : out std_logic_vector(2 downto 0);
TStates : out std_logic_vector(2 downto 0);
Prefix : out std_logic_vector(1 downto 0); -- None,BC,ED,DD/FD
Inc_PC : out std_logic;
Inc_WZ : out std_logic;
IncDec_16 : out std_logic_vector(3 downto 0); -- BC,DE,HL,SP 0 is inc
Read_To_Reg : out std_logic;
Read_To_Acc : out std_logic;
Set_BusA_To : out std_logic_vector(3 downto 0); -- B,C,D,E,H,L,DI/DB,A,SP(L),SP(M),0,F
Set_BusB_To : out std_logic_vector(3 downto 0); -- B,C,D,E,H,L,DI,A,SP(L),SP(M),1,F,PC(L),PC(M),0
ALU_Op : out std_logic_vector(3 downto 0);
-- ADD, ADC, SUB, SBC, AND, XOR, OR, CP, ROT, BIT, SET, RES, DAA, RLD, RRD, None
Save_ALU : out std_logic;
PreserveC : out std_logic;
Arith16 : out std_logic;
Set_Addr_To : out std_logic_vector(2 downto 0); -- aNone,aXY,aIOA,aSP,aBC,aDE,aZI
IORQ : out std_logic;
Jump : out std_logic;
JumpE : out std_logic;
JumpXY : out std_logic;
Call : out std_logic;
RstP : out std_logic;
LDZ : out std_logic;
LDW : out std_logic;
LDSPHL : out std_logic;
Special_LD : out std_logic_vector(2 downto 0); -- A,I;A,R;I,A;R,A;None
ExchangeDH : out std_logic;
ExchangeRp : out std_logic;
ExchangeAF : out std_logic;
ExchangeRS : out std_logic;
I_DJNZ : out std_logic;
I_CPL : out std_logic;
I_CCF : out std_logic;
I_SCF : out std_logic;
I_RETN : out std_logic;
I_BT : out std_logic;
I_BC : out std_logic;
I_BTR : out std_logic;
I_RLD : out std_logic;
I_RRD : out std_logic;
I_INRC : out std_logic;
SetDI : out std_logic;
SetEI : out std_logic;
IMode : out std_logic_vector(1 downto 0);
Halt : out std_logic;
NoRead : out std_logic;
Write : out std_logic
);
end component;
 
component T80_ALU
generic(
Mode : integer := 0;
Flag_C : integer := 0;
Flag_N : integer := 1;
Flag_P : integer := 2;
Flag_X : integer := 3;
Flag_H : integer := 4;
Flag_Y : integer := 5;
Flag_Z : integer := 6;
Flag_S : integer := 7
);
port(
Arith16 : in std_logic;
Z16 : in std_logic;
ALU_Op : in std_logic_vector(3 downto 0);
IR : in std_logic_vector(5 downto 0);
ISet : in std_logic_vector(1 downto 0);
BusA : in std_logic_vector(7 downto 0);
BusB : in std_logic_vector(7 downto 0);
F_In : in std_logic_vector(7 downto 0);
Q : out std_logic_vector(7 downto 0);
F_Out : out std_logic_vector(7 downto 0)
);
end component;
 
end;
/VHDL/t80/T80.vhd
0,0 → 1,1073
--
-- Z80 compatible microprocessor core
--
-- Version : 0247
--
-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org)
--
-- All rights reserved
--
-- Redistribution and use in source and synthezised forms, with or without
-- modification, are permitted provided that the following conditions are met:
--
-- Redistributions of source code must retain the above copyright notice,
-- this list of conditions and the following disclaimer.
--
-- Redistributions in synthesized form must reproduce the above copyright
-- notice, this list of conditions and the following disclaimer in the
-- documentation and/or other materials provided with the distribution.
--
-- Neither the name of the author nor the names of other contributors may
-- be used to endorse or promote products derived from this software without
-- specific prior written permission.
--
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-- POSSIBILITY OF SUCH DAMAGE.
--
-- Please report bugs to the author, but before you do so, please
-- make sure that this is not a derivative work and that
-- you have the latest version of this file.
--
-- The latest version of this file can be found at:
-- http://www.opencores.org/cvsweb.shtml/t80/
--
-- Limitations :
--
-- File history :
--
-- 0208 : First complete release
--
-- 0210 : Fixed wait and halt
--
-- 0211 : Fixed Refresh addition and IM 1
--
-- 0214 : Fixed mostly flags, only the block instructions now fail the zex regression test
--
-- 0232 : Removed refresh address output for Mode > 1 and added DJNZ M1_n fix by Mike Johnson
--
-- 0235 : Added clock enable and IM 2 fix by Mike Johnson
--
-- 0237 : Changed 8080 I/O address output, added IntE output
--
-- 0238 : Fixed (IX/IY+d) timing and 16 bit ADC and SBC zero flag
--
-- 0240 : Added interrupt ack fix by Mike Johnson, changed (IX/IY+d) timing and changed flags in GB mode
--
-- 0242 : Added I/O wait, fixed refresh address, moved some registers to RAM
--
-- 0247 : Fixed bus req/ack cycle
--
 
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use work.T80_Pack.all;
 
entity T80 is
generic(
Mode : integer := 0; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB
IOWait : integer := 0; -- 1 => Single cycle I/O, 1 => Std I/O cycle
Flag_C : integer := 0;
Flag_N : integer := 1;
Flag_P : integer := 2;
Flag_X : integer := 3;
Flag_H : integer := 4;
Flag_Y : integer := 5;
Flag_Z : integer := 6;
Flag_S : integer := 7
);
port(
RESET_n : in std_logic;
CLK_n : in std_logic;
CEN : in std_logic;
WAIT_n : in std_logic;
INT_n : in std_logic;
NMI_n : in std_logic;
BUSRQ_n : in std_logic;
M1_n : out std_logic;
IORQ : out std_logic;
NoRead : out std_logic;
Write : out std_logic;
RFSH_n : out std_logic;
HALT_n : out std_logic;
BUSAK_n : out std_logic;
A : out std_logic_vector(15 downto 0);
DInst : in std_logic_vector(7 downto 0);
DI : in std_logic_vector(7 downto 0);
DO : out std_logic_vector(7 downto 0);
MC : out std_logic_vector(2 downto 0);
TS : out std_logic_vector(2 downto 0);
IntCycle_n : out std_logic;
IntE : out std_logic;
Stop : out std_logic
);
end T80;
 
architecture rtl of T80 is
 
constant aNone : std_logic_vector(2 downto 0) := "111";
constant aBC : std_logic_vector(2 downto 0) := "000";
constant aDE : std_logic_vector(2 downto 0) := "001";
constant aXY : std_logic_vector(2 downto 0) := "010";
constant aIOA : std_logic_vector(2 downto 0) := "100";
constant aSP : std_logic_vector(2 downto 0) := "101";
constant aZI : std_logic_vector(2 downto 0) := "110";
 
-- Registers
signal ACC, F : std_logic_vector(7 downto 0);
signal Ap, Fp : std_logic_vector(7 downto 0);
signal I : std_logic_vector(7 downto 0);
signal R : unsigned(7 downto 0);
signal SP, PC : unsigned(15 downto 0);
signal RegDIH : std_logic_vector(7 downto 0);
signal RegDIL : std_logic_vector(7 downto 0);
signal RegBusA : std_logic_vector(15 downto 0);
signal RegBusB : std_logic_vector(15 downto 0);
signal RegBusC : std_logic_vector(15 downto 0);
signal RegAddrA_r : std_logic_vector(2 downto 0);
signal RegAddrA : std_logic_vector(2 downto 0);
signal RegAddrB_r : std_logic_vector(2 downto 0);
signal RegAddrB : std_logic_vector(2 downto 0);
signal RegAddrC : std_logic_vector(2 downto 0);
signal RegWEH : std_logic;
signal RegWEL : std_logic;
signal Alternate : std_logic;
 
-- Help Registers
signal TmpAddr : std_logic_vector(15 downto 0); -- Temporary address register
signal IR : std_logic_vector(7 downto 0); -- Instruction register
signal ISet : std_logic_vector(1 downto 0); -- Instruction set selector
signal RegBusA_r : std_logic_vector(15 downto 0);
 
signal ID16 : signed(15 downto 0);
signal Save_Mux : std_logic_vector(7 downto 0);
 
signal TState : unsigned(2 downto 0);
signal MCycle : std_logic_vector(2 downto 0);
signal IntE_FF1 : std_logic;
signal IntE_FF2 : std_logic;
signal Halt_FF : std_logic;
signal BusReq_s : std_logic;
signal BusAck : std_logic;
signal ClkEn : std_logic;
signal NMI_s : std_logic;
signal INT_s : std_logic;
signal IStatus : std_logic_vector(1 downto 0);
 
signal DI_Reg : std_logic_vector(7 downto 0);
signal T_Res : std_logic;
signal XY_State : std_logic_vector(1 downto 0);
signal Pre_XY_F_M : std_logic_vector(2 downto 0);
signal NextIs_XY_Fetch : std_logic;
signal XY_Ind : std_logic;
signal No_BTR : std_logic;
signal BTR_r : std_logic;
signal Auto_Wait : std_logic;
signal Auto_Wait_t1 : std_logic;
signal Auto_Wait_t2 : std_logic;
signal IncDecZ : std_logic;
 
-- ALU signals
signal BusB : std_logic_vector(7 downto 0);
signal BusA : std_logic_vector(7 downto 0);
signal ALU_Q : std_logic_vector(7 downto 0);
signal F_Out : std_logic_vector(7 downto 0);
 
-- Registered micro code outputs
signal Read_To_Reg_r : std_logic_vector(4 downto 0);
signal Arith16_r : std_logic;
signal Z16_r : std_logic;
signal ALU_Op_r : std_logic_vector(3 downto 0);
signal Save_ALU_r : std_logic;
signal PreserveC_r : std_logic;
signal MCycles : std_logic_vector(2 downto 0);
 
-- Micro code outputs
signal MCycles_d : std_logic_vector(2 downto 0);
signal TStates : std_logic_vector(2 downto 0);
signal IntCycle : std_logic;
signal NMICycle : std_logic;
signal Inc_PC : std_logic;
signal Inc_WZ : std_logic;
signal IncDec_16 : std_logic_vector(3 downto 0);
signal Prefix : std_logic_vector(1 downto 0);
signal Read_To_Acc : std_logic;
signal Read_To_Reg : std_logic;
signal Set_BusB_To : std_logic_vector(3 downto 0);
signal Set_BusA_To : std_logic_vector(3 downto 0);
signal ALU_Op : std_logic_vector(3 downto 0);
signal Save_ALU : std_logic;
signal PreserveC : std_logic;
signal Arith16 : std_logic;
signal Set_Addr_To : std_logic_vector(2 downto 0);
signal Jump : std_logic;
signal JumpE : std_logic;
signal JumpXY : std_logic;
signal Call : std_logic;
signal RstP : std_logic;
signal LDZ : std_logic;
signal LDW : std_logic;
signal LDSPHL : std_logic;
signal IORQ_i : std_logic;
signal Special_LD : std_logic_vector(2 downto 0);
signal ExchangeDH : std_logic;
signal ExchangeRp : std_logic;
signal ExchangeAF : std_logic;
signal ExchangeRS : std_logic;
signal I_DJNZ : std_logic;
signal I_CPL : std_logic;
signal I_CCF : std_logic;
signal I_SCF : std_logic;
signal I_RETN : std_logic;
signal I_BT : std_logic;
signal I_BC : std_logic;
signal I_BTR : std_logic;
signal I_RLD : std_logic;
signal I_RRD : std_logic;
signal I_INRC : std_logic;
signal SetDI : std_logic;
signal SetEI : std_logic;
signal IMode : std_logic_vector(1 downto 0);
signal Halt : std_logic;
 
begin
 
mcode : T80_MCode
generic map(
Mode => Mode,
Flag_C => Flag_C,
Flag_N => Flag_N,
Flag_P => Flag_P,
Flag_X => Flag_X,
Flag_H => Flag_H,
Flag_Y => Flag_Y,
Flag_Z => Flag_Z,
Flag_S => Flag_S)
port map(
IR => IR,
ISet => ISet,
MCycle => MCycle,
F => F,
NMICycle => NMICycle,
IntCycle => IntCycle,
MCycles => MCycles_d,
TStates => TStates,
Prefix => Prefix,
Inc_PC => Inc_PC,
Inc_WZ => Inc_WZ,
IncDec_16 => IncDec_16,
Read_To_Acc => Read_To_Acc,
Read_To_Reg => Read_To_Reg,
Set_BusB_To => Set_BusB_To,
Set_BusA_To => Set_BusA_To,
ALU_Op => ALU_Op,
Save_ALU => Save_ALU,
PreserveC => PreserveC,
Arith16 => Arith16,
Set_Addr_To => Set_Addr_To,
IORQ => IORQ_i,
Jump => Jump,
JumpE => JumpE,
JumpXY => JumpXY,
Call => Call,
RstP => RstP,
LDZ => LDZ,
LDW => LDW,
LDSPHL => LDSPHL,
Special_LD => Special_LD,
ExchangeDH => ExchangeDH,
ExchangeRp => ExchangeRp,
ExchangeAF => ExchangeAF,
ExchangeRS => ExchangeRS,
I_DJNZ => I_DJNZ,
I_CPL => I_CPL,
I_CCF => I_CCF,
I_SCF => I_SCF,
I_RETN => I_RETN,
I_BT => I_BT,
I_BC => I_BC,
I_BTR => I_BTR,
I_RLD => I_RLD,
I_RRD => I_RRD,
I_INRC => I_INRC,
SetDI => SetDI,
SetEI => SetEI,
IMode => IMode,
Halt => Halt,
NoRead => NoRead,
Write => Write);
 
alu : T80_ALU
generic map(
Mode => Mode,
Flag_C => Flag_C,
Flag_N => Flag_N,
Flag_P => Flag_P,
Flag_X => Flag_X,
Flag_H => Flag_H,
Flag_Y => Flag_Y,
Flag_Z => Flag_Z,
Flag_S => Flag_S)
port map(
Arith16 => Arith16_r,
Z16 => Z16_r,
ALU_Op => ALU_Op_r,
IR => IR(5 downto 0),
ISet => ISet,
BusA => BusA,
BusB => BusB,
F_In => F,
Q => ALU_Q,
F_Out => F_Out);
 
ClkEn <= CEN and not BusAck;
 
T_Res <= '1' when TState = unsigned(TStates) else '0';
 
NextIs_XY_Fetch <= '1' when XY_State /= "00" and XY_Ind = '0' and
((Set_Addr_To = aXY) or
(MCycle = "001" and IR = "11001011") or
(MCycle = "001" and IR = "00110110")) else '0';
 
Save_Mux <= BusB when ExchangeRp = '1' else
DI_Reg when Save_ALU_r = '0' else
ALU_Q;
 
process (RESET_n, CLK_n)
begin
if RESET_n = '0' then
PC <= (others => '0'); -- Program Counter
A <= (others => '0');
TmpAddr <= (others => '0');
IR <= "00000000";
ISet <= "00";
XY_State <= "00";
IStatus <= "00";
MCycles <= "000";
DO <= "00000000";
 
ACC <= (others => '1');
F <= (others => '1');
Ap <= (others => '1');
Fp <= (others => '1');
I <= (others => '0');
R <= (others => '0');
SP <= (others => '1');
Alternate <= '0';
 
Read_To_Reg_r <= "00000";
F <= (others => '1');
Arith16_r <= '0';
BTR_r <= '0';
Z16_r <= '0';
ALU_Op_r <= "0000";
Save_ALU_r <= '0';
PreserveC_r <= '0';
XY_Ind <= '0';
 
elsif CLK_n'event and CLK_n = '1' then
 
if ClkEn = '1' then
 
ALU_Op_r <= "0000";
Save_ALU_r <= '0';
Read_To_Reg_r <= "00000";
 
MCycles <= MCycles_d;
 
if IMode /= "11" then
IStatus <= IMode;
end if;
 
Arith16_r <= Arith16;
PreserveC_r <= PreserveC;
if ISet = "10" and ALU_OP(2) = '0' and ALU_OP(0) = '1' and MCycle = "011" then
Z16_r <= '1';
else
Z16_r <= '0';
end if;
 
if MCycle = "001" and TState(2) = '0' then
-- MCycle = 1 and TState = 1, 2, or 3
 
if TState = 2 and Wait_n = '1' then
if Mode < 2 then
A(7 downto 0) <= std_logic_vector(R);
A(15 downto 8) <= I;
R(6 downto 0) <= R(6 downto 0) + 1;
end if;
 
if Jump = '0' and Call = '0' and NMICycle = '0' and IntCycle = '0' and not (Halt_FF = '1' or Halt = '1') then
PC <= PC + 1;
end if;
 
if IntCycle = '1' and IStatus = "01" then
IR <= "11111111";
elsif Halt_FF = '1' or (IntCycle = '1' and IStatus = "10") or NMICycle = '1' then
IR <= "00000000";
else
IR <= DInst;
end if;
 
ISet <= "00";
if Prefix /= "00" then
if Prefix = "11" then
if IR(5) = '1' then
XY_State <= "10";
else
XY_State <= "01";
end if;
else
if Prefix = "10" then
XY_State <= "00";
XY_Ind <= '0';
end if;
ISet <= Prefix;
end if;
else
XY_State <= "00";
XY_Ind <= '0';
end if;
end if;
 
else
-- either (MCycle > 1) OR (MCycle = 1 AND TState > 3)
 
if MCycle = "110" then
XY_Ind <= '1';
if Prefix = "01" then
ISet <= "01";
end if;
end if;
 
if T_Res = '1' then
BTR_r <= (I_BT or I_BC or I_BTR) and not No_BTR;
if Jump = '1' then
A(15 downto 8) <= DI_Reg;
A(7 downto 0) <= TmpAddr(7 downto 0);
PC(15 downto 8) <= unsigned(DI_Reg);
PC(7 downto 0) <= unsigned(TmpAddr(7 downto 0));
elsif JumpXY = '1' then
A <= RegBusC;
PC <= unsigned(RegBusC);
elsif Call = '1' or RstP = '1' then
A <= TmpAddr;
PC <= unsigned(TmpAddr);
elsif MCycle = MCycles and NMICycle = '1' then
A <= "0000000001100110";
PC <= "0000000001100110";
elsif MCycle = "011" and IntCycle = '1' and IStatus = "10" then
A(15 downto 8) <= I;
A(7 downto 0) <= TmpAddr(7 downto 0);
PC(15 downto 8) <= unsigned(I);
PC(7 downto 0) <= unsigned(TmpAddr(7 downto 0));
else
case Set_Addr_To is
when aXY =>
if XY_State = "00" then
A <= RegBusC;
else
if NextIs_XY_Fetch = '1' then
A <= std_logic_vector(PC);
else
A <= TmpAddr;
end if;
end if;
when aIOA =>
if Mode = 3 then
-- Memory map I/O on GBZ80
A(15 downto 8) <= (others => '1');
elsif Mode = 2 then
-- Duplicate I/O address on 8080
A(15 downto 8) <= DI_Reg;
else
A(15 downto 8) <= ACC;
end if;
A(7 downto 0) <= DI_Reg;
when aSP =>
A <= std_logic_vector(SP);
when aBC =>
if Mode = 3 and IORQ_i = '1' then
-- Memory map I/O on GBZ80
A(15 downto 8) <= (others => '1');
A(7 downto 0) <= RegBusC(7 downto 0);
else
A <= RegBusC;
end if;
when aDE =>
A <= RegBusC;
when aZI =>
if Inc_WZ = '1' then
A <= std_logic_vector(unsigned(TmpAddr) + 1);
else
A(15 downto 8) <= DI_Reg;
A(7 downto 0) <= TmpAddr(7 downto 0);
end if;
when others =>
A <= std_logic_vector(PC);
end case;
end if;
 
Save_ALU_r <= Save_ALU;
ALU_Op_r <= ALU_Op;
 
if I_CPL = '1' then
-- CPL
ACC <= not ACC;
F(Flag_Y) <= not ACC(5);
F(Flag_H) <= '1';
F(Flag_X) <= not ACC(3);
F(Flag_N) <= '1';
end if;
if I_CCF = '1' then
-- CCF
F(Flag_C) <= not F(Flag_C);
F(Flag_Y) <= ACC(5);
F(Flag_H) <= F(Flag_C);
F(Flag_X) <= ACC(3);
F(Flag_N) <= '0';
end if;
if I_SCF = '1' then
-- SCF
F(Flag_C) <= '1';
F(Flag_Y) <= ACC(5);
F(Flag_H) <= '0';
F(Flag_X) <= ACC(3);
F(Flag_N) <= '0';
end if;
end if;
 
if TState = 2 and Wait_n = '1' then
if ISet = "01" and MCycle = "111" then
IR <= DInst;
end if;
if JumpE = '1' then
PC <= unsigned(signed(PC) + signed(DI_Reg));
elsif Inc_PC = '1' then
PC <= PC + 1;
end if;
if BTR_r = '1' then
PC <= PC - 2;
end if;
if RstP = '1' then
TmpAddr <= (others =>'0');
TmpAddr(5 downto 3) <= IR(5 downto 3);
end if;
end if;
if TState = 3 and MCycle = "110" then
TmpAddr <= std_logic_vector(signed(RegBusC) + signed(DI_Reg));
end if;
 
if (TState = 2 and Wait_n = '1') or (TState = 4 and MCycle = "001") then
if IncDec_16(2 downto 0) = "111" then
if IncDec_16(3) = '1' then
SP <= SP - 1;
else
SP <= SP + 1;
end if;
end if;
end if;
 
if LDSPHL = '1' then
SP <= unsigned(RegBusC);
end if;
if ExchangeAF = '1' then
Ap <= ACC;
ACC <= Ap;
Fp <= F;
F <= Fp;
end if;
if ExchangeRS = '1' then
Alternate <= not Alternate;
end if;
end if;
 
if TState = 3 then
if LDZ = '1' then
TmpAddr(7 downto 0) <= DI_Reg;
end if;
if LDW = '1' then
TmpAddr(15 downto 8) <= DI_Reg;
end if;
 
if Special_LD(2) = '1' then
case Special_LD(1 downto 0) is
when "00" =>
ACC <= I;
F(Flag_P) <= IntE_FF2;
when "01" =>
ACC <= std_logic_vector(R);
F(Flag_P) <= IntE_FF2;
when "10" =>
I <= ACC;
when others =>
R <= unsigned(ACC);
end case;
end if;
end if;
 
if (I_DJNZ = '0' and Save_ALU_r = '1') or ALU_Op_r = "1001" then
if Mode = 3 then
F(6) <= F_Out(6);
F(5) <= F_Out(5);
F(7) <= F_Out(7);
if PreserveC_r = '0' then
F(4) <= F_Out(4);
end if;
else
F(7 downto 1) <= F_Out(7 downto 1);
if PreserveC_r = '0' then
F(Flag_C) <= F_Out(0);
end if;
end if;
end if;
if T_Res = '1' and I_INRC = '1' then
F(Flag_H) <= '0';
F(Flag_N) <= '0';
if DI_Reg(7 downto 0) = "00000000" then
F(Flag_Z) <= '1';
else
F(Flag_Z) <= '0';
end if;
F(Flag_S) <= DI_Reg(7);
F(Flag_P) <= not (DI_Reg(0) xor DI_Reg(1) xor DI_Reg(2) xor DI_Reg(3) xor
DI_Reg(4) xor DI_Reg(5) xor DI_Reg(6) xor DI_Reg(7));
end if;
 
if TState = 1 and Auto_Wait_t1 = '0' then
DO <= BusB;
if I_RLD = '1' then
DO(3 downto 0) <= BusA(3 downto 0);
DO(7 downto 4) <= BusB(3 downto 0);
end if;
if I_RRD = '1' then
DO(3 downto 0) <= BusB(7 downto 4);
DO(7 downto 4) <= BusA(3 downto 0);
end if;
end if;
 
if T_Res = '1' then
Read_To_Reg_r(3 downto 0) <= Set_BusA_To;
Read_To_Reg_r(4) <= Read_To_Reg;
if Read_To_Acc = '1' then
Read_To_Reg_r(3 downto 0) <= "0111";
Read_To_Reg_r(4) <= '1';
end if;
end if;
 
if TState = 1 and I_BT = '1' then
F(Flag_X) <= ALU_Q(3);
F(Flag_Y) <= ALU_Q(1);
F(Flag_H) <= '0';
F(Flag_N) <= '0';
end if;
if I_BC = '1' or I_BT = '1' then
F(Flag_P) <= IncDecZ;
end if;
 
if (TState = 1 and Save_ALU_r = '0' and Auto_Wait_t1 = '0') or
(Save_ALU_r = '1' and ALU_OP_r /= "0111") then
case Read_To_Reg_r is
when "10111" =>
ACC <= Save_Mux;
when "10110" =>
DO <= Save_Mux;
when "11000" =>
SP(7 downto 0) <= unsigned(Save_Mux);
when "11001" =>
SP(15 downto 8) <= unsigned(Save_Mux);
when "11011" =>
F <= Save_Mux;
when others =>
end case;
end if;
 
end if;
 
end if;
 
end process;
 
---------------------------------------------------------------------------
--
-- BC('), DE('), HL('), IX and IY
--
---------------------------------------------------------------------------
process (CLK_n)
begin
if CLK_n'event and CLK_n = '1' then
if ClkEn = '1' then
-- Bus A / Write
RegAddrA_r <= Alternate & Set_BusA_To(2 downto 1);
if XY_Ind = '0' and XY_State /= "00" and Set_BusA_To(2 downto 1) = "10" then
RegAddrA_r <= XY_State(1) & "11";
end if;
 
-- Bus B
RegAddrB_r <= Alternate & Set_BusB_To(2 downto 1);
if XY_Ind = '0' and XY_State /= "00" and Set_BusB_To(2 downto 1) = "10" then
RegAddrB_r <= XY_State(1) & "11";
end if;
 
-- Address from register
RegAddrC <= Alternate & Set_Addr_To(1 downto 0);
-- Jump (HL), LD SP,HL
if (JumpXY = '1' or LDSPHL = '1') then
RegAddrC <= Alternate & "10";
end if;
if ((JumpXY = '1' or LDSPHL = '1') and XY_State /= "00") or (MCycle = "110") then
RegAddrC <= XY_State(1) & "11";
end if;
 
if I_DJNZ = '1' and Save_ALU_r = '1' and Mode < 2 then
IncDecZ <= F_Out(Flag_Z);
end if;
if (TState = 2 or (TState = 3 and MCycle = "001")) and IncDec_16(2 downto 0) = "100" then
if ID16 = 0 then
IncDecZ <= '0';
else
IncDecZ <= '1';
end if;
end if;
 
RegBusA_r <= RegBusA;
end if;
end if;
end process;
 
RegAddrA <=
-- 16 bit increment/decrement
Alternate & IncDec_16(1 downto 0) when (TState = 2 or
(TState = 3 and MCycle = "001" and IncDec_16(2) = '1')) and XY_State = "00" else
XY_State(1) & "11" when (TState = 2 or
(TState = 3 and MCycle = "001" and IncDec_16(2) = '1')) and IncDec_16(1 downto 0) = "10" else
-- EX HL,DL
Alternate & "10" when ExchangeDH = '1' and TState = 3 else
Alternate & "01" when ExchangeDH = '1' and TState = 4 else
-- Bus A / Write
RegAddrA_r;
 
RegAddrB <=
-- EX HL,DL
Alternate & "01" when ExchangeDH = '1' and TState = 3 else
-- Bus B
RegAddrB_r;
 
ID16 <= signed(RegBusA) - 1 when IncDec_16(3) = '1' else
signed(RegBusA) + 1;
 
process (Save_ALU_r, Auto_Wait_t1, ALU_OP_r, Read_To_Reg_r,
ExchangeDH, IncDec_16, MCycle, TState, Wait_n)
begin
RegWEH <= '0';
RegWEL <= '0';
if (TState = 1 and Save_ALU_r = '0' and Auto_Wait_t1 = '0') or
(Save_ALU_r = '1' and ALU_OP_r /= "0111") then
case Read_To_Reg_r is
when "10000" | "10001" | "10010" | "10011" | "10100" | "10101" =>
RegWEH <= not Read_To_Reg_r(0);
RegWEL <= Read_To_Reg_r(0);
when others =>
end case;
end if;
 
if ExchangeDH = '1' and (TState = 3 or TState = 4) then
RegWEH <= '1';
RegWEL <= '1';
end if;
 
if IncDec_16(2) = '1' and ((TState = 2 and Wait_n = '1' and MCycle /= "001") or (TState = 3 and MCycle = "001")) then
case IncDec_16(1 downto 0) is
when "00" | "01" | "10" =>
RegWEH <= '1';
RegWEL <= '1';
when others =>
end case;
end if;
end process;
 
process (Save_Mux, RegBusB, RegBusA_r, ID16,
ExchangeDH, IncDec_16, MCycle, TState, Wait_n)
begin
RegDIH <= Save_Mux;
RegDIL <= Save_Mux;
 
if ExchangeDH = '1' and TState = 3 then
RegDIH <= RegBusB(15 downto 8);
RegDIL <= RegBusB(7 downto 0);
end if;
if ExchangeDH = '1' and TState = 4 then
RegDIH <= RegBusA_r(15 downto 8);
RegDIL <= RegBusA_r(7 downto 0);
end if;
 
if IncDec_16(2) = '1' and ((TState = 2 and MCycle /= "001") or (TState = 3 and MCycle = "001")) then
RegDIH <= std_logic_vector(ID16(15 downto 8));
RegDIL <= std_logic_vector(ID16(7 downto 0));
end if;
end process;
 
Regs : T80_Reg
port map(
Clk => CLK_n,
CEN => ClkEn,
WEH => RegWEH,
WEL => RegWEL,
AddrA => RegAddrA,
AddrB => RegAddrB,
AddrC => RegAddrC,
DIH => RegDIH,
DIL => RegDIL,
DOAH => RegBusA(15 downto 8),
DOAL => RegBusA(7 downto 0),
DOBH => RegBusB(15 downto 8),
DOBL => RegBusB(7 downto 0),
DOCH => RegBusC(15 downto 8),
DOCL => RegBusC(7 downto 0));
 
---------------------------------------------------------------------------
--
-- Buses
--
---------------------------------------------------------------------------
process (CLK_n)
begin
if CLK_n'event and CLK_n = '1' then
if ClkEn = '1' then
case Set_BusB_To is
when "0111" =>
BusB <= ACC;
when "0000" | "0001" | "0010" | "0011" | "0100" | "0101" =>
if Set_BusB_To(0) = '1' then
BusB <= RegBusB(7 downto 0);
else
BusB <= RegBusB(15 downto 8);
end if;
when "0110" =>
BusB <= DI_Reg;
when "1000" =>
BusB <= std_logic_vector(SP(7 downto 0));
when "1001" =>
BusB <= std_logic_vector(SP(15 downto 8));
when "1010" =>
BusB <= "00000001";
when "1011" =>
BusB <= F;
when "1100" =>
BusB <= std_logic_vector(PC(7 downto 0));
when "1101" =>
BusB <= std_logic_vector(PC(15 downto 8));
when "1110" =>
BusB <= "00000000";
when others =>
BusB <= "--------";
end case;
 
case Set_BusA_To is
when "0111" =>
BusA <= ACC;
when "0000" | "0001" | "0010" | "0011" | "0100" | "0101" =>
if Set_BusA_To(0) = '1' then
BusA <= RegBusA(7 downto 0);
else
BusA <= RegBusA(15 downto 8);
end if;
when "0110" =>
BusA <= DI_Reg;
when "1000" =>
BusA <= std_logic_vector(SP(7 downto 0));
when "1001" =>
BusA <= std_logic_vector(SP(15 downto 8));
when "1010" =>
BusA <= "00000000";
when others =>
BusB <= "--------";
end case;
end if;
end if;
end process;
 
---------------------------------------------------------------------------
--
-- Generate external control signals
--
---------------------------------------------------------------------------
process (RESET_n,CLK_n)
begin
if RESET_n = '0' then
RFSH_n <= '1';
elsif CLK_n'event and CLK_n = '1' then
if CEN = '1' then
if MCycle = "001" and ((TState = 2 and Wait_n = '1') or TState = 3) then
RFSH_n <= '0';
else
RFSH_n <= '1';
end if;
end if;
end if;
end process;
 
MC <= std_logic_vector(MCycle);
TS <= std_logic_vector(TState);
DI_Reg <= DI;
HALT_n <= not Halt_FF;
BUSAK_n <= not BusAck;
IntCycle_n <= not IntCycle;
IntE <= IntE_FF1;
IORQ <= IORQ_i;
Stop <= I_DJNZ;
 
-------------------------------------------------------------------------
--
-- Syncronise inputs
--
-------------------------------------------------------------------------
process (RESET_n, CLK_n)
variable OldNMI_n : std_logic;
begin
if RESET_n = '0' then
BusReq_s <= '0';
INT_s <= '0';
NMI_s <= '0';
OldNMI_n := '0';
elsif CLK_n'event and CLK_n = '1' then
if CEN = '1' then
BusReq_s <= not BUSRQ_n;
INT_s <= not INT_n;
if NMICycle = '1' then
NMI_s <= '0';
elsif NMI_n = '0' and OldNMI_n = '1' then
NMI_s <= '1';
end if;
OldNMI_n := NMI_n;
end if;
end if;
end process;
 
-------------------------------------------------------------------------
--
-- Main state machine
--
-------------------------------------------------------------------------
process (RESET_n, CLK_n)
begin
if RESET_n = '0' then
MCycle <= "001";
TState <= "000";
Pre_XY_F_M <= "000";
Halt_FF <= '0';
BusAck <= '0';
NMICycle <= '0';
IntCycle <= '0';
IntE_FF1 <= '0';
IntE_FF2 <= '0';
No_BTR <= '0';
Auto_Wait_t1 <= '0';
Auto_Wait_t2 <= '0';
M1_n <= '1';
elsif CLK_n'event and CLK_n = '1' then
if CEN = '1' then
if T_Res = '1' then
Auto_Wait_t1 <= '0';
else
Auto_Wait_t1 <= Auto_Wait or IORQ_i;
end if;
Auto_Wait_t2 <= Auto_Wait_t1;
No_BTR <= (I_BT and (not IR(4) or not F(Flag_P))) or
(I_BC and (not IR(4) or F(Flag_Z) or not F(Flag_P))) or
(I_BTR and (not IR(4) or F(Flag_Z)));
if TState = 2 then
if SetEI = '1' then
IntE_FF1 <= '1';
IntE_FF2 <= '1';
end if;
if I_RETN = '1' then
IntE_FF1 <= IntE_FF2;
end if;
end if;
if TState = 3 then
if SetDI = '1' then
IntE_FF1 <= '0';
IntE_FF2 <= '0';
end if;
end if;
if IntCycle = '1' or NMICycle = '1' then
Halt_FF <= '0';
end if;
if MCycle = "001" and TState = 2 and Wait_n = '1' then
M1_n <= '1';
end if;
if BusReq_s = '1' and BusAck = '1' then
else
BusAck <= '0';
if TState = 2 and Wait_n = '0' then
elsif T_Res = '1' then
if Halt = '1' then
Halt_FF <= '1';
end if;
if BusReq_s = '1' then
BusAck <= '1';
else
TState <= "001";
if NextIs_XY_Fetch = '1' then
MCycle <= "110";
Pre_XY_F_M <= MCycle;
if IR = "00110110" and Mode = 0 then
Pre_XY_F_M <= "010";
end if;
elsif (MCycle = "111") or
(MCycle = "110" and Mode = 1 and ISet /= "01") then
MCycle <= std_logic_vector(unsigned(Pre_XY_F_M) + 1);
elsif (MCycle = MCycles) or
No_BTR = '1' or
(MCycle = "010" and I_DJNZ = '1' and IncDecZ = '1') then
M1_n <= '0';
MCycle <= "001";
IntCycle <= '0';
NMICycle <= '0';
if NMI_s = '1' and Prefix = "00" then
NMICycle <= '1';
IntE_FF1 <= '0';
elsif (IntE_FF1 = '1' and INT_s = '1') and Prefix = "00" and SetEI = '0' then
IntCycle <= '1';
IntE_FF1 <= '0';
IntE_FF2 <= '0';
end if;
else
MCycle <= std_logic_vector(unsigned(MCycle) + 1);
end if;
end if;
else
if (Auto_Wait = '1' and Auto_Wait_t2 = '0') nor
(IOWait = 1 and IORQ_i = '1' and Auto_Wait_t1 = '0') then
TState <= TState + 1;
end if;
end if;
end if;
if TState = 0 then
M1_n <= '0';
end if;
end if;
end if;
end process;
 
process (IntCycle, NMICycle, MCycle)
begin
Auto_Wait <= '0';
if IntCycle = '1' or NMICycle = '1' then
if MCycle = "001" then
Auto_Wait <= '1';
end if;
end if;
end process;
 
end;
/VHDL/t80/T8080se.vhd
0,0 → 1,185
--
-- 8080 compatible microprocessor core, synchronous top level with clock enable
-- Different timing than the original 8080
-- Inputs needs to be synchronous and outputs may glitch
--
-- Version : 0242
--
-- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org)
--
-- All rights reserved
--
-- Redistribution and use in source and synthezised forms, with or without
-- modification, are permitted provided that the following conditions are met:
--
-- Redistributions of source code must retain the above copyright notice,
-- this list of conditions and the following disclaimer.
--
-- Redistributions in synthesized form must reproduce the above copyright
-- notice, this list of conditions and the following disclaimer in the
-- documentation and/or other materials provided with the distribution.
--
-- Neither the name of the author nor the names of other contributors may
-- be used to endorse or promote products derived from this software without
-- specific prior written permission.
--
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-- POSSIBILITY OF SUCH DAMAGE.
--
-- Please report bugs to the author, but before you do so, please
-- make sure that this is not a derivative work and that
-- you have the latest version of this file.
--
-- The latest version of this file can be found at:
-- http://www.opencores.org/cvsweb.shtml/t80/
--
-- Limitations :
-- STACK status output not supported
--
-- File history :
--
-- 0237 : First version
--
-- 0238 : Updated for T80 interface change
--
-- 0240 : Updated for T80 interface change
--
-- 0242 : Updated for T80 interface change
--
 
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use work.T80_Pack.all;
 
entity T8080se is
generic(
Mode : integer := 2; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB
T2Write : integer := 0 -- 0 => WR_n active in T3, /=0 => WR_n active in T2
);
port(
RESET_n : in std_logic;
CLK : in std_logic;
CLKEN : in std_logic;
READY : in std_logic;
HOLD : in std_logic;
INT : in std_logic;
INTE : out std_logic;
DBIN : out std_logic;
SYNC : out std_logic;
VAIT : out std_logic;
HLDA : out std_logic;
WR_n : out std_logic;
A : out std_logic_vector(15 downto 0);
DI : in std_logic_vector(7 downto 0);
DO : out std_logic_vector(7 downto 0)
);
end T8080se;
 
architecture rtl of T8080se is
 
signal IntCycle_n : std_logic;
signal NoRead : std_logic;
signal Write : std_logic;
signal IORQ : std_logic;
signal INT_n : std_logic;
signal HALT_n : std_logic;
signal BUSRQ_n : std_logic;
signal BUSAK_n : std_logic;
signal DO_i : std_logic_vector(7 downto 0);
signal DI_Reg : std_logic_vector(7 downto 0);
signal MCycle : std_logic_vector(2 downto 0);
signal TState : std_logic_vector(2 downto 0);
signal One : std_logic;
 
begin
 
INT_n <= not INT;
BUSRQ_n <= HOLD;
HLDA <= not BUSAK_n;
SYNC <= '1' when TState = "001" else '0';
VAIT <= '1' when TState = "010" else '0';
One <= '1';
 
DO(0) <= not IntCycle_n when TState = "001" else DO_i(0); -- INTA
DO(1) <= Write when TState = "001" else DO_i(1); -- WO_n
DO(2) <= DO_i(2); -- STACK not supported !!!!!!!!!!
DO(3) <= not HALT_n when TState = "001" else DO_i(3); -- HLTA
DO(4) <= IORQ and Write when TState = "001" else DO_i(4); -- OUT
DO(5) <= DO_i(5) when TState /= "001" else '1' when MCycle = "001" else '0'; -- M1
DO(6) <= IORQ and not Write when TState = "001" else DO_i(6); -- INP
DO(7) <= not IORQ and not Write and IntCycle_n when TState = "001" else DO_i(7); -- MEMR
 
u0 : T80
generic map(
Mode => Mode,
IOWait => 0)
port map(
CEN => CLKEN,
M1_n => open,
IORQ => IORQ,
NoRead => NoRead,
Write => Write,
RFSH_n => open,
HALT_n => HALT_n,
WAIT_n => READY,
INT_n => INT_n,
NMI_n => One,
RESET_n => RESET_n,
BUSRQ_n => One,
BUSAK_n => BUSAK_n,
CLK_n => CLK,
A => A,
DInst => DI,
DI => DI_Reg,
DO => DO_i,
MC => MCycle,
TS => TState,
IntCycle_n => IntCycle_n,
IntE => INTE);
 
process (RESET_n, CLK)
begin
if RESET_n = '0' then
DBIN <= '0';
WR_n <= '1';
DI_Reg <= "00000000";
elsif CLK'event and CLK = '1' then
if CLKEN = '1' then
DBIN <= '0';
WR_n <= '1';
if MCycle = "001" then
if TState = "001" or (TState = "010" and READY = '0') then
DBIN <= IntCycle_n;
end if;
else
if (TState = "001" or (TState = "010" and READY = '0')) and NoRead = '0' and Write = '0' then
DBIN <= '1';
end if;
if T2Write = 0 then
if TState = "010" and Write = '1' then
WR_n <= '0';
end if;
else
if (TState = "001" or (TState = "010" and READY = '0')) and Write = '1' then
WR_n <= '0';
end if;
end if;
end if;
if TState = "010" and READY = '1' then
DI_Reg <= DI;
end if;
end if;
end if;
end process;
 
end;
/VHDL/t80/T80_ALU.vhd
0,0 → 1,351
--
-- Z80 compatible microprocessor core
--
-- Version : 0247
--
-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org)
--
-- All rights reserved
--
-- Redistribution and use in source and synthezised forms, with or without
-- modification, are permitted provided that the following conditions are met:
--
-- Redistributions of source code must retain the above copyright notice,
-- this list of conditions and the following disclaimer.
--
-- Redistributions in synthesized form must reproduce the above copyright
-- notice, this list of conditions and the following disclaimer in the
-- documentation and/or other materials provided with the distribution.
--
-- Neither the name of the author nor the names of other contributors may
-- be used to endorse or promote products derived from this software without
-- specific prior written permission.
--
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-- POSSIBILITY OF SUCH DAMAGE.
--
-- Please report bugs to the author, but before you do so, please
-- make sure that this is not a derivative work and that
-- you have the latest version of this file.
--
-- The latest version of this file can be found at:
-- http://www.opencores.org/cvsweb.shtml/t80/
--
-- Limitations :
--
-- File history :
--
-- 0214 : Fixed mostly flags, only the block instructions now fail the zex regression test
--
-- 0238 : Fixed zero flag for 16 bit SBC and ADC
--
-- 0240 : Added GB operations
--
-- 0242 : Cleanup
--
-- 0247 : Cleanup
--
 
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
 
entity T80_ALU is
generic(
Mode : integer := 0;
Flag_C : integer := 0;
Flag_N : integer := 1;
Flag_P : integer := 2;
Flag_X : integer := 3;
Flag_H : integer := 4;
Flag_Y : integer := 5;
Flag_Z : integer := 6;
Flag_S : integer := 7
);
port(
Arith16 : in std_logic;
Z16 : in std_logic;
ALU_Op : in std_logic_vector(3 downto 0);
IR : in std_logic_vector(5 downto 0);
ISet : in std_logic_vector(1 downto 0);
BusA : in std_logic_vector(7 downto 0);
BusB : in std_logic_vector(7 downto 0);
F_In : in std_logic_vector(7 downto 0);
Q : out std_logic_vector(7 downto 0);
F_Out : out std_logic_vector(7 downto 0)
);
end T80_ALU;
 
architecture rtl of T80_ALU is
 
procedure AddSub(A : std_logic_vector;
B : std_logic_vector;
Sub : std_logic;
Carry_In : std_logic;
signal Res : out std_logic_vector;
signal Carry : out std_logic) is
variable B_i : unsigned(A'length - 1 downto 0);
variable Res_i : unsigned(A'length + 1 downto 0);
begin
if Sub = '1' then
B_i := not unsigned(B);
else
B_i := unsigned(B);
end if;
Res_i := unsigned("0" & A & Carry_In) + unsigned("0" & B_i & "1");
Carry <= Res_i(A'length + 1);
Res <= std_logic_vector(Res_i(A'length downto 1));
end;
 
-- AddSub variables (temporary signals)
signal UseCarry : std_logic;
signal Carry7_v : std_logic;
signal Overflow_v : std_logic;
signal HalfCarry_v : std_logic;
signal Carry_v : std_logic;
signal Q_v : std_logic_vector(7 downto 0);
 
signal BitMask : std_logic_vector(7 downto 0);
 
begin
 
with IR(5 downto 3) select BitMask <= "00000001" when "000",
"00000010" when "001",
"00000100" when "010",
"00001000" when "011",
"00010000" when "100",
"00100000" when "101",
"01000000" when "110",
"10000000" when others;
 
UseCarry <= not ALU_Op(2) and ALU_Op(0);
AddSub(BusA(3 downto 0), BusB(3 downto 0), ALU_Op(1), ALU_Op(1) xor (UseCarry and F_In(Flag_C)), Q_v(3 downto 0), HalfCarry_v);
AddSub(BusA(6 downto 4), BusB(6 downto 4), ALU_Op(1), HalfCarry_v, Q_v(6 downto 4), Carry7_v);
AddSub(BusA(7 downto 7), BusB(7 downto 7), ALU_Op(1), Carry7_v, Q_v(7 downto 7), Carry_v);
OverFlow_v <= Carry_v xor Carry7_v;
 
process (Arith16, ALU_OP, F_In, BusA, BusB, IR, Q_v, Carry_v, HalfCarry_v, OverFlow_v, BitMask, ISet, Z16)
variable Q_t : std_logic_vector(7 downto 0);
variable DAA_Q : unsigned(8 downto 0);
begin
Q_t := "--------";
F_Out <= F_In;
DAA_Q := "---------";
case ALU_Op is
when "0000" | "0001" | "0010" | "0011" | "0100" | "0101" | "0110" | "0111" =>
F_Out(Flag_N) <= '0';
F_Out(Flag_C) <= '0';
case ALU_OP(2 downto 0) is
when "000" | "001" => -- ADD, ADC
Q_t := Q_v;
F_Out(Flag_C) <= Carry_v;
F_Out(Flag_H) <= HalfCarry_v;
F_Out(Flag_P) <= OverFlow_v;
when "010" | "011" | "111" => -- SUB, SBC, CP
Q_t := Q_v;
F_Out(Flag_N) <= '1';
F_Out(Flag_C) <= not Carry_v;
F_Out(Flag_H) <= not HalfCarry_v;
F_Out(Flag_P) <= OverFlow_v;
when "100" => -- AND
Q_t(7 downto 0) := BusA and BusB;
F_Out(Flag_H) <= '1';
when "101" => -- XOR
Q_t(7 downto 0) := BusA xor BusB;
F_Out(Flag_H) <= '0';
when others => -- OR "110"
Q_t(7 downto 0) := BusA or BusB;
F_Out(Flag_H) <= '0';
end case;
if ALU_Op(2 downto 0) = "111" then -- CP
F_Out(Flag_X) <= BusB(3);
F_Out(Flag_Y) <= BusB(5);
else
F_Out(Flag_X) <= Q_t(3);
F_Out(Flag_Y) <= Q_t(5);
end if;
if Q_t(7 downto 0) = "00000000" then
F_Out(Flag_Z) <= '1';
if Z16 = '1' then
F_Out(Flag_Z) <= F_In(Flag_Z); -- 16 bit ADC,SBC
end if;
else
F_Out(Flag_Z) <= '0';
end if;
F_Out(Flag_S) <= Q_t(7);
case ALU_Op(2 downto 0) is
when "000" | "001" | "010" | "011" | "111" => -- ADD, ADC, SUB, SBC, CP
when others =>
F_Out(Flag_P) <= not (Q_t(0) xor Q_t(1) xor Q_t(2) xor Q_t(3) xor
Q_t(4) xor Q_t(5) xor Q_t(6) xor Q_t(7));
end case;
if Arith16 = '1' then
F_Out(Flag_S) <= F_In(Flag_S);
F_Out(Flag_Z) <= F_In(Flag_Z);
F_Out(Flag_P) <= F_In(Flag_P);
end if;
when "1100" =>
-- DAA
F_Out(Flag_H) <= F_In(Flag_H);
F_Out(Flag_C) <= F_In(Flag_C);
DAA_Q(7 downto 0) := unsigned(BusA);
DAA_Q(8) := '0';
if F_In(Flag_N) = '0' then
-- After addition
-- Alow > 9 or H = 1
if DAA_Q(3 downto 0) > 9 or F_In(Flag_H) = '1' then
if (DAA_Q(3 downto 0) > 9) then
F_Out(Flag_H) <= '1';
else
F_Out(Flag_H) <= '0';
end if;
DAA_Q := DAA_Q + 6;
end if;
-- new Ahigh > 9 or C = 1
if DAA_Q(8 downto 4) > 9 or F_In(Flag_C) = '1' then
DAA_Q := DAA_Q + 96; -- 0x60
end if;
else
-- After subtraction
if DAA_Q(3 downto 0) > 9 or F_In(Flag_H) = '1' then
if DAA_Q(3 downto 0) > 5 then
F_Out(Flag_H) <= '0';
end if;
DAA_Q(7 downto 0) := DAA_Q(7 downto 0) - 6;
end if;
if unsigned(BusA) > 153 or F_In(Flag_C) = '1' then
DAA_Q := DAA_Q - 352; -- 0x160
end if;
end if;
F_Out(Flag_X) <= DAA_Q(3);
F_Out(Flag_Y) <= DAA_Q(5);
F_Out(Flag_C) <= F_In(Flag_C) or DAA_Q(8);
Q_t := std_logic_vector(DAA_Q(7 downto 0));
if DAA_Q(7 downto 0) = "00000000" then
F_Out(Flag_Z) <= '1';
else
F_Out(Flag_Z) <= '0';
end if;
F_Out(Flag_S) <= DAA_Q(7);
F_Out(Flag_P) <= not (DAA_Q(0) xor DAA_Q(1) xor DAA_Q(2) xor DAA_Q(3) xor
DAA_Q(4) xor DAA_Q(5) xor DAA_Q(6) xor DAA_Q(7));
when "1101" | "1110" =>
-- RLD, RRD
Q_t(7 downto 4) := BusA(7 downto 4);
if ALU_Op(0) = '1' then
Q_t(3 downto 0) := BusB(7 downto 4);
else
Q_t(3 downto 0) := BusB(3 downto 0);
end if;
F_Out(Flag_H) <= '0';
F_Out(Flag_N) <= '0';
F_Out(Flag_X) <= Q_t(3);
F_Out(Flag_Y) <= Q_t(5);
if Q_t(7 downto 0) = "00000000" then
F_Out(Flag_Z) <= '1';
else
F_Out(Flag_Z) <= '0';
end if;
F_Out(Flag_S) <= Q_t(7);
F_Out(Flag_P) <= not (Q_t(0) xor Q_t(1) xor Q_t(2) xor Q_t(3) xor
Q_t(4) xor Q_t(5) xor Q_t(6) xor Q_t(7));
when "1001" =>
-- BIT
Q_t(7 downto 0) := BusB and BitMask;
F_Out(Flag_S) <= Q_t(7);
if Q_t(7 downto 0) = "00000000" then
F_Out(Flag_Z) <= '1';
F_Out(Flag_P) <= '1';
else
F_Out(Flag_Z) <= '0';
F_Out(Flag_P) <= '0';
end if;
F_Out(Flag_H) <= '1';
F_Out(Flag_N) <= '0';
F_Out(Flag_X) <= '0';
F_Out(Flag_Y) <= '0';
if IR(2 downto 0) /= "110" then
F_Out(Flag_X) <= BusB(3);
F_Out(Flag_Y) <= BusB(5);
end if;
when "1010" =>
-- SET
Q_t(7 downto 0) := BusB or BitMask;
when "1011" =>
-- RES
Q_t(7 downto 0) := BusB and not BitMask;
when "1000" =>
-- ROT
case IR(5 downto 3) is
when "000" => -- RLC
Q_t(7 downto 1) := BusA(6 downto 0);
Q_t(0) := BusA(7);
F_Out(Flag_C) <= BusA(7);
when "010" => -- RL
Q_t(7 downto 1) := BusA(6 downto 0);
Q_t(0) := F_In(Flag_C);
F_Out(Flag_C) <= BusA(7);
when "001" => -- RRC
Q_t(6 downto 0) := BusA(7 downto 1);
Q_t(7) := BusA(0);
F_Out(Flag_C) <= BusA(0);
when "011" => -- RR
Q_t(6 downto 0) := BusA(7 downto 1);
Q_t(7) := F_In(Flag_C);
F_Out(Flag_C) <= BusA(0);
when "100" => -- SLA
Q_t(7 downto 1) := BusA(6 downto 0);
Q_t(0) := '0';
F_Out(Flag_C) <= BusA(7);
when "110" => -- SLL (Undocumented) / SWAP
if Mode = 3 then
Q_t(7 downto 4) := BusA(3 downto 0);
Q_t(3 downto 0) := BusA(7 downto 4);
F_Out(Flag_C) <= '0';
else
Q_t(7 downto 1) := BusA(6 downto 0);
Q_t(0) := '1';
F_Out(Flag_C) <= BusA(7);
end if;
when "101" => -- SRA
Q_t(6 downto 0) := BusA(7 downto 1);
Q_t(7) := BusA(7);
F_Out(Flag_C) <= BusA(0);
when others => -- SRL
Q_t(6 downto 0) := BusA(7 downto 1);
Q_t(7) := '0';
F_Out(Flag_C) <= BusA(0);
end case;
F_Out(Flag_H) <= '0';
F_Out(Flag_N) <= '0';
F_Out(Flag_X) <= Q_t(3);
F_Out(Flag_Y) <= Q_t(5);
F_Out(Flag_S) <= Q_t(7);
if Q_t(7 downto 0) = "00000000" then
F_Out(Flag_Z) <= '1';
else
F_Out(Flag_Z) <= '0';
end if;
F_Out(Flag_P) <= not (Q_t(0) xor Q_t(1) xor Q_t(2) xor Q_t(3) xor
Q_t(4) xor Q_t(5) xor Q_t(6) xor Q_t(7));
if ISet = "00" then
F_Out(Flag_P) <= F_In(Flag_P);
F_Out(Flag_S) <= F_In(Flag_S);
F_Out(Flag_Z) <= F_In(Flag_Z);
end if;
when others =>
null;
end case;
Q <= Q_t;
end process;
 
end;
/VHDL/t80/T80a.vhd
0,0 → 1,253
--
-- Z80 compatible microprocessor core, asynchronous top level
--
-- Version : 0247
--
-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org)
--
-- All rights reserved
--
-- Redistribution and use in source and synthezised forms, with or without
-- modification, are permitted provided that the following conditions are met:
--
-- Redistributions of source code must retain the above copyright notice,
-- this list of conditions and the following disclaimer.
--
-- Redistributions in synthesized form must reproduce the above copyright
-- notice, this list of conditions and the following disclaimer in the
-- documentation and/or other materials provided with the distribution.
--
-- Neither the name of the author nor the names of other contributors may
-- be used to endorse or promote products derived from this software without
-- specific prior written permission.
--
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-- POSSIBILITY OF SUCH DAMAGE.
--
-- Please report bugs to the author, but before you do so, please
-- make sure that this is not a derivative work and that
-- you have the latest version of this file.
--
-- The latest version of this file can be found at:
-- http://www.opencores.org/cvsweb.shtml/t80/
--
-- Limitations :
--
-- File history :
--
-- 0208 : First complete release
--
-- 0211 : Fixed interrupt cycle
--
-- 0235 : Updated for T80 interface change
--
-- 0238 : Updated for T80 interface change
--
-- 0240 : Updated for T80 interface change
--
-- 0242 : Updated for T80 interface change
--
-- 0247 : Fixed bus req/ack cycle
--
 
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use work.T80_Pack.all;
 
entity T80a is
generic(
Mode : integer := 0 -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB
);
port(
RESET_n : in std_logic;
CLK_n : in std_logic;
WAIT_n : in std_logic;
INT_n : in std_logic;
NMI_n : in std_logic;
BUSRQ_n : in std_logic;
M1_n : out std_logic;
MREQ_n : out std_logic;
IORQ_n : out std_logic;
RD_n : out std_logic;
WR_n : out std_logic;
RFSH_n : out std_logic;
HALT_n : out std_logic;
BUSAK_n : out std_logic;
A : out std_logic_vector(15 downto 0);
D : inout std_logic_vector(7 downto 0)
);
end T80a;
 
architecture rtl of T80a is
 
signal CEN : std_logic;
signal Reset_s : std_logic;
signal IntCycle_n : std_logic;
signal IORQ : std_logic;
signal NoRead : std_logic;
signal Write : std_logic;
signal MREQ : std_logic;
signal MReq_Inhibit : std_logic;
signal Req_Inhibit : std_logic;
signal RD : std_logic;
signal MREQ_n_i : std_logic;
signal IORQ_n_i : std_logic;
signal RD_n_i : std_logic;
signal WR_n_i : std_logic;
signal RFSH_n_i : std_logic;
signal BUSAK_n_i : std_logic;
signal A_i : std_logic_vector(15 downto 0);
signal DO : std_logic_vector(7 downto 0);
signal DI_Reg : std_logic_vector (7 downto 0); -- Input synchroniser
signal Wait_s : std_logic;
signal MCycle : std_logic_vector(2 downto 0);
signal TState : std_logic_vector(2 downto 0);
 
begin
 
CEN <= '1';
 
BUSAK_n <= BUSAK_n_i;
MREQ_n_i <= not MREQ or (Req_Inhibit and MReq_Inhibit);
RD_n_i <= not RD or Req_Inhibit;
 
MREQ_n <= MREQ_n_i when BUSAK_n_i = '1' else 'Z';
IORQ_n <= IORQ_n_i when BUSAK_n_i = '1' else 'Z';
RD_n <= RD_n_i when BUSAK_n_i = '1' else 'Z';
WR_n <= WR_n_i when BUSAK_n_i = '1' else 'Z';
RFSH_n <= RFSH_n_i when BUSAK_n_i = '1' else 'Z';
A <= A_i when BUSAK_n_i = '1' else (others => 'Z');
D <= DO when Write = '1' and BUSAK_n_i = '1' else (others => 'Z');
 
process (RESET_n, CLK_n)
begin
if RESET_n = '0' then
Reset_s <= '0';
elsif CLK_n'event and CLK_n = '1' then
Reset_s <= '1';
end if;
end process;
 
u0 : T80
generic map(
Mode => Mode,
IOWait => 1)
port map(
CEN => CEN,
M1_n => M1_n,
IORQ => IORQ,
NoRead => NoRead,
Write => Write,
RFSH_n => RFSH_n_i,
HALT_n => HALT_n,
WAIT_n => Wait_s,
INT_n => INT_n,
NMI_n => NMI_n,
RESET_n => Reset_s,
BUSRQ_n => BUSRQ_n,
BUSAK_n => BUSAK_n_i,
CLK_n => CLK_n,
A => A_i,
DInst => D,
DI => DI_Reg,
DO => DO,
MC => MCycle,
TS => TState,
IntCycle_n => IntCycle_n);
 
process (CLK_n)
begin
if CLK_n'event and CLK_n = '0' then
Wait_s <= WAIT_n;
if TState = "011" and BUSAK_n_i = '1' then
DI_Reg <= to_x01(D);
end if;
end if;
end process;
 
process (Reset_s,CLK_n)
begin
if Reset_s = '0' then
WR_n_i <= '1';
elsif CLK_n'event and CLK_n = '1' then
WR_n_i <= '1';
if TState = "001" then -- To short for IO writes !!!!!!!!!!!!!!!!!!!
WR_n_i <= not Write;
end if;
end if;
end process;
 
process (Reset_s,CLK_n)
begin
if Reset_s = '0' then
Req_Inhibit <= '0';
elsif CLK_n'event and CLK_n = '1' then
if MCycle = "001" and TState = "010" then
Req_Inhibit <= '1';
else
Req_Inhibit <= '0';
end if;
end if;
end process;
 
process (Reset_s,CLK_n)
begin
if Reset_s = '0' then
MReq_Inhibit <= '0';
elsif CLK_n'event and CLK_n = '0' then
if MCycle = "001" and TState = "010" then
MReq_Inhibit <= '1';
else
MReq_Inhibit <= '0';
end if;
end if;
end process;
 
process(Reset_s,CLK_n)
begin
if Reset_s = '0' then
RD <= '0';
IORQ_n_i <= '1';
MREQ <= '0';
elsif CLK_n'event and CLK_n = '0' then
 
if MCycle = "001" then
if TState = "001" then
RD <= IntCycle_n;
MREQ <= IntCycle_n;
IORQ_n_i <= IntCycle_n;
end if;
if TState = "011" then
RD <= '0';
IORQ_n_i <= '1';
MREQ <= '1';
end if;
if TState = "100" then
MREQ <= '0';
end if;
else
if TState = "001" and NoRead = '0' then
RD <= not Write;
IORQ_n_i <= not IORQ;
MREQ <= not IORQ;
end if;
if TState = "011" then
RD <= '0';
IORQ_n_i <= '1';
MREQ <= '0';
end if;
end if;
end if;
end process;
 
end;
/VHDL/t80/SSRAMX.vhd
0,0 → 1,132
--
-- Xilinx Block RAM, 8 bit wide and variable size (Min. 512 bytes)
--
-- Version : 0247
--
-- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org)
--
-- All rights reserved
--
-- Redistribution and use in source and synthezised forms, with or without
-- modification, are permitted provided that the following conditions are met:
--
-- Redistributions of source code must retain the above copyright notice,
-- this list of conditions and the following disclaimer.
--
-- Redistributions in synthesized form must reproduce the above copyright
-- notice, this list of conditions and the following disclaimer in the
-- documentation and/or other materials provided with the distribution.
--
-- Neither the name of the author nor the names of other contributors may
-- be used to endorse or promote products derived from this software without
-- specific prior written permission.
--
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-- POSSIBILITY OF SUCH DAMAGE.
--
-- Please report bugs to the author, but before you do so, please
-- make sure that this is not a derivative work and that
-- you have the latest version of this file.
--
-- The latest version of this file can be found at:
-- http://www.opencores.org/cvsweb.shtml/t51/
--
-- Limitations :
--
-- File history :
--
-- 0240 : Initial release
--
-- 0242 : Changed RAMB4_S8 to map by name
--
-- 0247 : Added RAMB4_S8 component declaration
--
 
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
 
entity SSRAM is
generic(
AddrWidth : integer := 11;
DataWidth : integer := 8
);
port(
Clk : in std_logic;
CE_n : in std_logic;
WE_n : in std_logic;
A : in std_logic_vector(AddrWidth - 1 downto 0);
DIn : in std_logic_vector(DataWidth - 1 downto 0);
DOut : out std_logic_vector(DataWidth - 1 downto 0)
);
end SSRAM;
 
architecture rtl of SSRAM is
 
component RAMB4_S8
port(
DO : out std_logic_vector(7 downto 0);
ADDR : in std_logic_vector(8 downto 0);
CLK : in std_ulogic;
DI : in std_logic_vector(7 downto 0);
EN : in std_ulogic;
RST : in std_ulogic;
WE : in std_ulogic);
end component;
 
constant RAMs : integer := (2 ** AddrWidth) / 512;
 
type bRAMOut_a is array(0 to RAMs - 1) of std_logic_vector(7 downto 0);
 
signal bRAMOut : bRAMOut_a;
signal biA_r : integer;
signal A_r : unsigned(A'left downto 0);
-- signal A_i : std_logic_vector(8 downto 0);
signal WEA : std_logic_vector(RAMs - 1 downto 0);
 
begin
 
process (Clk)
begin
if Clk'event and Clk = '1' then
A_r <= unsigned(A);
end if;
end process;
 
biA_r <= to_integer(A_r(A'left downto 9));
-- A_i <= std_logic_vector(A_r(8 downto 0)) when (CE_n nor WE_n) = '1' else A(8 downto 0);
 
bG1: for I in 0 to RAMs - 1 generate
begin
WEA(I) <= '1' when (CE_n nor WE_n) = '1' and biA_r = I else '0';
BSSRAM : RAMB4_S8
port map(
DI => DIn,
EN => '1',
WE => WEA(I),
RST => '0',
CLK => Clk,
ADDR => A,
DO => bRAMOut(I));
end generate;
 
process (biA_r, bRAMOut)
begin
DOut <= bRAMOut(0);
for I in 1 to RAMs - 1 loop
if biA_r = I then
DOut <= bRAMOut(I);
end if;
end loop;
end process;
 
end;
/VHDL/t80/T80_MCode.vhd
0,0 → 1,1934
--
-- Z80 compatible microprocessor core
--
-- Version : 0242
--
-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org)
--
-- All rights reserved
--
-- Redistribution and use in source and synthezised forms, with or without
-- modification, are permitted provided that the following conditions are met:
--
-- Redistributions of source code must retain the above copyright notice,
-- this list of conditions and the following disclaimer.
--
-- Redistributions in synthesized form must reproduce the above copyright
-- notice, this list of conditions and the following disclaimer in the
-- documentation and/or other materials provided with the distribution.
--
-- Neither the name of the author nor the names of other contributors may
-- be used to endorse or promote products derived from this software without
-- specific prior written permission.
--
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-- POSSIBILITY OF SUCH DAMAGE.
--
-- Please report bugs to the author, but before you do so, please
-- make sure that this is not a derivative work and that
-- you have the latest version of this file.
--
-- The latest version of this file can be found at:
-- http://www.opencores.org/cvsweb.shtml/t80/
--
-- Limitations :
--
-- File history :
--
-- 0208 : First complete release
--
-- 0211 : Fixed IM 1
--
-- 0214 : Fixed mostly flags, only the block instructions now fail the zex regression test
--
-- 0235 : Added IM 2 fix by Mike Johnson
--
-- 0238 : Added NoRead signal
--
-- 0238b: Fixed instruction timing for POP and DJNZ
--
-- 0240 : Added (IX/IY+d) states, removed op-codes from mode 2 and added all remaining mode 3 op-codes
--
-- 0242 : Fixed I/O instruction timing, cleanup
--
 
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
 
entity T80_MCode is
generic(
Mode : integer := 0;
Flag_C : integer := 0;
Flag_N : integer := 1;
Flag_P : integer := 2;
Flag_X : integer := 3;
Flag_H : integer := 4;
Flag_Y : integer := 5;
Flag_Z : integer := 6;
Flag_S : integer := 7
);
port(
IR : in std_logic_vector(7 downto 0);
ISet : in std_logic_vector(1 downto 0);
MCycle : in std_logic_vector(2 downto 0);
F : in std_logic_vector(7 downto 0);
NMICycle : in std_logic;
IntCycle : in std_logic;
MCycles : out std_logic_vector(2 downto 0);
TStates : out std_logic_vector(2 downto 0);
Prefix : out std_logic_vector(1 downto 0); -- None,BC,ED,DD/FD
Inc_PC : out std_logic;
Inc_WZ : out std_logic;
IncDec_16 : out std_logic_vector(3 downto 0); -- BC,DE,HL,SP 0 is inc
Read_To_Reg : out std_logic;
Read_To_Acc : out std_logic;
Set_BusA_To : out std_logic_vector(3 downto 0); -- B,C,D,E,H,L,DI/DB,A,SP(L),SP(M),0,F
Set_BusB_To : out std_logic_vector(3 downto 0); -- B,C,D,E,H,L,DI,A,SP(L),SP(M),1,F,PC(L),PC(M),0
ALU_Op : out std_logic_vector(3 downto 0);
-- ADD, ADC, SUB, SBC, AND, XOR, OR, CP, ROT, BIT, SET, RES, DAA, RLD, RRD, None
Save_ALU : out std_logic;
PreserveC : out std_logic;
Arith16 : out std_logic;
Set_Addr_To : out std_logic_vector(2 downto 0); -- aNone,aXY,aIOA,aSP,aBC,aDE,aZI
IORQ : out std_logic;
Jump : out std_logic;
JumpE : out std_logic;
JumpXY : out std_logic;
Call : out std_logic;
RstP : out std_logic;
LDZ : out std_logic;
LDW : out std_logic;
LDSPHL : out std_logic;
Special_LD : out std_logic_vector(2 downto 0); -- A,I;A,R;I,A;R,A;None
ExchangeDH : out std_logic;
ExchangeRp : out std_logic;
ExchangeAF : out std_logic;
ExchangeRS : out std_logic;
I_DJNZ : out std_logic;
I_CPL : out std_logic;
I_CCF : out std_logic;
I_SCF : out std_logic;
I_RETN : out std_logic;
I_BT : out std_logic;
I_BC : out std_logic;
I_BTR : out std_logic;
I_RLD : out std_logic;
I_RRD : out std_logic;
I_INRC : out std_logic;
SetDI : out std_logic;
SetEI : out std_logic;
IMode : out std_logic_vector(1 downto 0);
Halt : out std_logic;
NoRead : out std_logic;
Write : out std_logic
);
end T80_MCode;
 
architecture rtl of T80_MCode is
 
constant aNone : std_logic_vector(2 downto 0) := "111";
constant aBC : std_logic_vector(2 downto 0) := "000";
constant aDE : std_logic_vector(2 downto 0) := "001";
constant aXY : std_logic_vector(2 downto 0) := "010";
constant aIOA : std_logic_vector(2 downto 0) := "100";
constant aSP : std_logic_vector(2 downto 0) := "101";
constant aZI : std_logic_vector(2 downto 0) := "110";
-- constant aNone : std_logic_vector(2 downto 0) := "000";
-- constant aXY : std_logic_vector(2 downto 0) := "001";
-- constant aIOA : std_logic_vector(2 downto 0) := "010";
-- constant aSP : std_logic_vector(2 downto 0) := "011";
-- constant aBC : std_logic_vector(2 downto 0) := "100";
-- constant aDE : std_logic_vector(2 downto 0) := "101";
-- constant aZI : std_logic_vector(2 downto 0) := "110";
 
function is_cc_true(
F : std_logic_vector(7 downto 0);
cc : bit_vector(2 downto 0)
) return boolean is
begin
if Mode = 3 then
case cc is
when "000" => return F(7) = '0'; -- NZ
when "001" => return F(7) = '1'; -- Z
when "010" => return F(4) = '0'; -- NC
when "011" => return F(4) = '1'; -- C
when "100" => return false;
when "101" => return false;
when "110" => return false;
when "111" => return false;
end case;
else
case cc is
when "000" => return F(6) = '0'; -- NZ
when "001" => return F(6) = '1'; -- Z
when "010" => return F(0) = '0'; -- NC
when "011" => return F(0) = '1'; -- C
when "100" => return F(2) = '0'; -- PO
when "101" => return F(2) = '1'; -- PE
when "110" => return F(7) = '0'; -- P
when "111" => return F(7) = '1'; -- M
end case;
end if;
end;
 
begin
 
process (IR, ISet, MCycle, F, NMICycle, IntCycle)
variable DDD : std_logic_vector(2 downto 0);
variable SSS : std_logic_vector(2 downto 0);
variable DPair : std_logic_vector(1 downto 0);
variable IRB : bit_vector(7 downto 0);
begin
DDD := IR(5 downto 3);
SSS := IR(2 downto 0);
DPair := IR(5 downto 4);
IRB := to_bitvector(IR);
 
MCycles <= "001";
if MCycle = "001" then
TStates <= "100";
else
TStates <= "011";
end if;
Prefix <= "00";
Inc_PC <= '0';
Inc_WZ <= '0';
IncDec_16 <= "0000";
Read_To_Acc <= '0';
Read_To_Reg <= '0';
Set_BusB_To <= "0000";
Set_BusA_To <= "0000";
ALU_Op <= "0" & IR(5 downto 3);
Save_ALU <= '0';
PreserveC <= '0';
Arith16 <= '0';
IORQ <= '0';
Set_Addr_To <= aNone;
Jump <= '0';
JumpE <= '0';
JumpXY <= '0';
Call <= '0';
RstP <= '0';
LDZ <= '0';
LDW <= '0';
LDSPHL <= '0';
Special_LD <= "000";
ExchangeDH <= '0';
ExchangeRp <= '0';
ExchangeAF <= '0';
ExchangeRS <= '0';
I_DJNZ <= '0';
I_CPL <= '0';
I_CCF <= '0';
I_SCF <= '0';
I_RETN <= '0';
I_BT <= '0';
I_BC <= '0';
I_BTR <= '0';
I_RLD <= '0';
I_RRD <= '0';
I_INRC <= '0';
SetDI <= '0';
SetEI <= '0';
IMode <= "11";
Halt <= '0';
NoRead <= '0';
Write <= '0';
 
case ISet is
when "00" =>
 
------------------------------------------------------------------------------
--
-- Unprefixed instructions
--
------------------------------------------------------------------------------
 
case IRB is
-- 8 BIT LOAD GROUP
when "01000000"|"01000001"|"01000010"|"01000011"|"01000100"|"01000101"|"01000111"
|"01001000"|"01001001"|"01001010"|"01001011"|"01001100"|"01001101"|"01001111"
|"01010000"|"01010001"|"01010010"|"01010011"|"01010100"|"01010101"|"01010111"
|"01011000"|"01011001"|"01011010"|"01011011"|"01011100"|"01011101"|"01011111"
|"01100000"|"01100001"|"01100010"|"01100011"|"01100100"|"01100101"|"01100111"
|"01101000"|"01101001"|"01101010"|"01101011"|"01101100"|"01101101"|"01101111"
|"01111000"|"01111001"|"01111010"|"01111011"|"01111100"|"01111101"|"01111111" =>
-- LD r,r'
Set_BusB_To(2 downto 0) <= SSS;
ExchangeRp <= '1';
Set_BusA_To(2 downto 0) <= DDD;
Read_To_Reg <= '1';
when "00000110"|"00001110"|"00010110"|"00011110"|"00100110"|"00101110"|"00111110" =>
-- LD r,n
MCycles <= "010";
case to_integer(unsigned(MCycle)) is
when 2 =>
Inc_PC <= '1';
Set_BusA_To(2 downto 0) <= DDD;
Read_To_Reg <= '1';
when others => null;
end case;
when "01000110"|"01001110"|"01010110"|"01011110"|"01100110"|"01101110"|"01111110" =>
-- LD r,(HL)
MCycles <= "010";
case to_integer(unsigned(MCycle)) is
when 1 =>
Set_Addr_To <= aXY;
when 2 =>
Set_BusA_To(2 downto 0) <= DDD;
Read_To_Reg <= '1';
when others => null;
end case;
when "01110000"|"01110001"|"01110010"|"01110011"|"01110100"|"01110101"|"01110111" =>
-- LD (HL),r
MCycles <= "010";
case to_integer(unsigned(MCycle)) is
when 1 =>
Set_Addr_To <= aXY;
Set_BusB_To(2 downto 0) <= SSS;
Set_BusB_To(3) <= '0';
when 2 =>
Write <= '1';
when others => null;
end case;
when "00110110" =>
-- LD (HL),n
MCycles <= "011";
case to_integer(unsigned(MCycle)) is
when 2 =>
Inc_PC <= '1';
Set_Addr_To <= aXY;
Set_BusB_To(2 downto 0) <= SSS;
Set_BusB_To(3) <= '0';
when 3 =>
Write <= '1';
when others => null;
end case;
when "00001010" =>
-- LD A,(BC)
MCycles <= "010";
case to_integer(unsigned(MCycle)) is
when 1 =>
Set_Addr_To <= aBC;
when 2 =>
Read_To_Acc <= '1';
when others => null;
end case;
when "00011010" =>
-- LD A,(DE)
MCycles <= "010";
case to_integer(unsigned(MCycle)) is
when 1 =>
Set_Addr_To <= aDE;
when 2 =>
Read_To_Acc <= '1';
when others => null;
end case;
when "00111010" =>
if Mode = 3 then
-- LDD A,(HL)
MCycles <= "010";
case to_integer(unsigned(MCycle)) is
when 1 =>
Set_Addr_To <= aXY;
when 2 =>
Read_To_Acc <= '1';
IncDec_16 <= "1110";
when others => null;
end case;
else
-- LD A,(nn)
MCycles <= "100";
case to_integer(unsigned(MCycle)) is
when 2 =>
Inc_PC <= '1';
LDZ <= '1';
when 3 =>
Set_Addr_To <= aZI;
Inc_PC <= '1';
when 4 =>
Read_To_Acc <= '1';
when others => null;
end case;
end if;
when "00000010" =>
-- LD (BC),A
MCycles <= "010";
case to_integer(unsigned(MCycle)) is
when 1 =>
Set_Addr_To <= aBC;
Set_BusB_To <= "0111";
when 2 =>
Write <= '1';
when others => null;
end case;
when "00010010" =>
-- LD (DE),A
MCycles <= "010";
case to_integer(unsigned(MCycle)) is
when 1 =>
Set_Addr_To <= aDE;
Set_BusB_To <= "0111";
when 2 =>
Write <= '1';
when others => null;
end case;
when "00110010" =>
if Mode = 3 then
-- LDD (HL),A
MCycles <= "010";
case to_integer(unsigned(MCycle)) is
when 1 =>
Set_Addr_To <= aXY;
Set_BusB_To <= "0111";
when 2 =>
Write <= '1';
IncDec_16 <= "1110";
when others => null;
end case;
else
-- LD (nn),A
MCycles <= "100";
case to_integer(unsigned(MCycle)) is
when 2 =>
Inc_PC <= '1';
LDZ <= '1';
when 3 =>
Set_Addr_To <= aZI;
Inc_PC <= '1';
Set_BusB_To <= "0111";
when 4 =>
Write <= '1';
when others => null;
end case;
end if;
 
-- 16 BIT LOAD GROUP
when "00000001"|"00010001"|"00100001"|"00110001" =>
-- LD dd,nn
MCycles <= "011";
case to_integer(unsigned(MCycle)) is
when 2 =>
Inc_PC <= '1';
Read_To_Reg <= '1';
if DPAIR = "11" then
Set_BusA_To(3 downto 0) <= "1000";
else
Set_BusA_To(2 downto 1) <= DPAIR;
Set_BusA_To(0) <= '1';
end if;
when 3 =>
Inc_PC <= '1';
Read_To_Reg <= '1';
if DPAIR = "11" then
Set_BusA_To(3 downto 0) <= "1001";
else
Set_BusA_To(2 downto 1) <= DPAIR;
Set_BusA_To(0) <= '0';
end if;
when others => null;
end case;
when "00101010" =>
if Mode = 3 then
-- LDI A,(HL)
MCycles <= "010";
case to_integer(unsigned(MCycle)) is
when 1 =>
Set_Addr_To <= aXY;
when 2 =>
Read_To_Acc <= '1';
IncDec_16 <= "0110";
when others => null;
end case;
else
-- LD HL,(nn)
MCycles <= "101";
case to_integer(unsigned(MCycle)) is
when 2 =>
Inc_PC <= '1';
LDZ <= '1';
when 3 =>
Set_Addr_To <= aZI;
Inc_PC <= '1';
LDW <= '1';
when 4 =>
Set_BusA_To(2 downto 0) <= "101"; -- L
Read_To_Reg <= '1';
Inc_WZ <= '1';
Set_Addr_To <= aZI;
when 5 =>
Set_BusA_To(2 downto 0) <= "100"; -- H
Read_To_Reg <= '1';
when others => null;
end case;
end if;
when "00100010" =>
if Mode = 3 then
-- LDI (HL),A
MCycles <= "010";
case to_integer(unsigned(MCycle)) is
when 1 =>
Set_Addr_To <= aXY;
Set_BusB_To <= "0111";
when 2 =>
Write <= '1';
IncDec_16 <= "0110";
when others => null;
end case;
else
-- LD (nn),HL
MCycles <= "101";
case to_integer(unsigned(MCycle)) is
when 2 =>
Inc_PC <= '1';
LDZ <= '1';
when 3 =>
Set_Addr_To <= aZI;
Inc_PC <= '1';
LDW <= '1';
Set_BusB_To <= "0101"; -- L
when 4 =>
Inc_WZ <= '1';
Set_Addr_To <= aZI;
Write <= '1';
Set_BusB_To <= "0100"; -- H
when 5 =>
Write <= '1';
when others => null;
end case;
end if;
when "11111001" =>
-- LD SP,HL
TStates <= "110";
LDSPHL <= '1';
when "11000101"|"11010101"|"11100101"|"11110101" =>
-- PUSH qq
MCycles <= "011";
case to_integer(unsigned(MCycle)) is
when 1 =>
TStates <= "101";
IncDec_16 <= "1111";
Set_Addr_TO <= aSP;
if DPAIR = "11" then
Set_BusB_To <= "0111";
else
Set_BusB_To(2 downto 1) <= DPAIR;
Set_BusB_To(0) <= '0';
Set_BusB_To(3) <= '0';
end if;
when 2 =>
IncDec_16 <= "1111";
Set_Addr_To <= aSP;
if DPAIR = "11" then
Set_BusB_To <= "1011";
else
Set_BusB_To(2 downto 1) <= DPAIR;
Set_BusB_To(0) <= '1';
Set_BusB_To(3) <= '0';
end if;
Write <= '1';
when 3 =>
Write <= '1';
when others => null;
end case;
when "11000001"|"11010001"|"11100001"|"11110001" =>
-- POP qq
MCycles <= "011";
case to_integer(unsigned(MCycle)) is
when 1 =>
Set_Addr_To <= aSP;
when 2 =>
IncDec_16 <= "0111";
Set_Addr_To <= aSP;
Read_To_Reg <= '1';
if DPAIR = "11" then
Set_BusA_To(3 downto 0) <= "1011";
else
Set_BusA_To(2 downto 1) <= DPAIR;
Set_BusA_To(0) <= '1';
end if;
when 3 =>
IncDec_16 <= "0111";
Read_To_Reg <= '1';
if DPAIR = "11" then
Set_BusA_To(3 downto 0) <= "0111";
else
Set_BusA_To(2 downto 1) <= DPAIR;
Set_BusA_To(0) <= '0';
end if;
when others => null;
end case;
 
-- EXCHANGE, BLOCK TRANSFER AND SEARCH GROUP
when "11101011" =>
if Mode /= 3 then
-- EX DE,HL
ExchangeDH <= '1';
end if;
when "00001000" =>
if Mode = 3 then
-- LD (nn),SP
MCycles <= "101";
case to_integer(unsigned(MCycle)) is
when 2 =>
Inc_PC <= '1';
LDZ <= '1';
when 3 =>
Set_Addr_To <= aZI;
Inc_PC <= '1';
LDW <= '1';
Set_BusB_To <= "1000";
when 4 =>
Inc_WZ <= '1';
Set_Addr_To <= aZI;
Write <= '1';
Set_BusB_To <= "1001";
when 5 =>
Write <= '1';
when others => null;
end case;
elsif Mode < 2 then
-- EX AF,AF'
ExchangeAF <= '1';
end if;
when "11011001" =>
if Mode = 3 then
-- RETI
MCycles <= "011";
case to_integer(unsigned(MCycle)) is
when 1 =>
Set_Addr_TO <= aSP;
when 2 =>
IncDec_16 <= "0111";
Set_Addr_To <= aSP;
LDZ <= '1';
when 3 =>
Jump <= '1';
IncDec_16 <= "0111";
I_RETN <= '1';
SetEI <= '1';
when others => null;
end case;
elsif Mode < 2 then
-- EXX
ExchangeRS <= '1';
end if;
when "11100011" =>
if Mode /= 3 then
-- EX (SP),HL
MCycles <= "101";
case to_integer(unsigned(MCycle)) is
when 1 =>
Set_Addr_To <= aSP;
when 2 =>
Read_To_Reg <= '1';
Set_BusA_To <= "0101";
Set_BusB_To <= "0101";
Set_Addr_To <= aSP;
when 3 =>
IncDec_16 <= "0111";
Set_Addr_To <= aSP;
TStates <= "100";
Write <= '1';
when 4 =>
Read_To_Reg <= '1';
Set_BusA_To <= "0100";
Set_BusB_To <= "0100";
Set_Addr_To <= aSP;
when 5 =>
IncDec_16 <= "1111";
TStates <= "101";
Write <= '1';
when others => null;
end case;
end if;
 
-- 8 BIT ARITHMETIC AND LOGICAL GROUP
when "10000000"|"10000001"|"10000010"|"10000011"|"10000100"|"10000101"|"10000111"
|"10001000"|"10001001"|"10001010"|"10001011"|"10001100"|"10001101"|"10001111"
|"10010000"|"10010001"|"10010010"|"10010011"|"10010100"|"10010101"|"10010111"
|"10011000"|"10011001"|"10011010"|"10011011"|"10011100"|"10011101"|"10011111"
|"10100000"|"10100001"|"10100010"|"10100011"|"10100100"|"10100101"|"10100111"
|"10101000"|"10101001"|"10101010"|"10101011"|"10101100"|"10101101"|"10101111"
|"10110000"|"10110001"|"10110010"|"10110011"|"10110100"|"10110101"|"10110111"
|"10111000"|"10111001"|"10111010"|"10111011"|"10111100"|"10111101"|"10111111" =>
-- ADD A,r
-- ADC A,r
-- SUB A,r
-- SBC A,r
-- AND A,r
-- OR A,r
-- XOR A,r
-- CP A,r
Set_BusB_To(2 downto 0) <= SSS;
Set_BusA_To(2 downto 0) <= "111";
Read_To_Reg <= '1';
Save_ALU <= '1';
when "10000110"|"10001110"|"10010110"|"10011110"|"10100110"|"10101110"|"10110110"|"10111110" =>
-- ADD A,(HL)
-- ADC A,(HL)
-- SUB A,(HL)
-- SBC A,(HL)
-- AND A,(HL)
-- OR A,(HL)
-- XOR A,(HL)
-- CP A,(HL)
MCycles <= "010";
case to_integer(unsigned(MCycle)) is
when 1 =>
Set_Addr_To <= aXY;
when 2 =>
Read_To_Reg <= '1';
Save_ALU <= '1';
Set_BusB_To(2 downto 0) <= SSS;
Set_BusA_To(2 downto 0) <= "111";
when others => null;
end case;
when "11000110"|"11001110"|"11010110"|"11011110"|"11100110"|"11101110"|"11110110"|"11111110" =>
-- ADD A,n
-- ADC A,n
-- SUB A,n
-- SBC A,n
-- AND A,n
-- OR A,n
-- XOR A,n
-- CP A,n
MCycles <= "010";
if MCycle = "010" then
Inc_PC <= '1';
Read_To_Reg <= '1';
Save_ALU <= '1';
Set_BusB_To(2 downto 0) <= SSS;
Set_BusA_To(2 downto 0) <= "111";
end if;
when "00000100"|"00001100"|"00010100"|"00011100"|"00100100"|"00101100"|"00111100" =>
-- INC r
Set_BusB_To <= "1010";
Set_BusA_To(2 downto 0) <= DDD;
Read_To_Reg <= '1';
Save_ALU <= '1';
PreserveC <= '1';
ALU_Op <= "0000";
when "00110100" =>
-- INC (HL)
MCycles <= "011";
case to_integer(unsigned(MCycle)) is
when 1 =>
Set_Addr_To <= aXY;
when 2 =>
TStates <= "100";
Set_Addr_To <= aXY;
Read_To_Reg <= '1';
Save_ALU <= '1';
PreserveC <= '1';
ALU_Op <= "0000";
Set_BusB_To <= "1010";
Set_BusA_To(2 downto 0) <= DDD;
when 3 =>
Write <= '1';
when others => null;
end case;
when "00000101"|"00001101"|"00010101"|"00011101"|"00100101"|"00101101"|"00111101" =>
-- DEC r
Set_BusB_To <= "1010";
Set_BusA_To(2 downto 0) <= DDD;
Read_To_Reg <= '1';
Save_ALU <= '1';
PreserveC <= '1';
ALU_Op <= "0010";
when "00110101" =>
-- DEC (HL)
MCycles <= "011";
case to_integer(unsigned(MCycle)) is
when 1 =>
Set_Addr_To <= aXY;
when 2 =>
TStates <= "100";
Set_Addr_To <= aXY;
ALU_Op <= "0010";
Read_To_Reg <= '1';
Save_ALU <= '1';
PreserveC <= '1';
Set_BusB_To <= "1010";
Set_BusA_To(2 downto 0) <= DDD;
when 3 =>
Write <= '1';
when others => null;
end case;
 
-- GENERAL PURPOSE ARITHMETIC AND CPU CONTROL GROUPS
when "00100111" =>
-- DAA
Set_BusA_To(2 downto 0) <= "111";
Read_To_Reg <= '1';
ALU_Op <= "1100";
Save_ALU <= '1';
when "00101111" =>
-- CPL
I_CPL <= '1';
when "00111111" =>
-- CCF
I_CCF <= '1';
when "00110111" =>
-- SCF
I_SCF <= '1';
when "00000000" =>
if NMICycle = '1' then
-- NMI
MCycles <= "011";
case to_integer(unsigned(MCycle)) is
when 1 =>
TStates <= "101";
IncDec_16 <= "1111";
Set_Addr_To <= aSP;
Set_BusB_To <= "1101";
when 2 =>
TStates <= "100";
Write <= '1';
IncDec_16 <= "1111";
Set_Addr_To <= aSP;
Set_BusB_To <= "1100";
when 3 =>
TStates <= "100";
Write <= '1';
when others => null;
end case;
elsif IntCycle = '1' then
-- INT (IM 2)
MCycles <= "101";
case to_integer(unsigned(MCycle)) is
when 1 =>
LDZ <= '1';
TStates <= "101";
IncDec_16 <= "1111";
Set_Addr_To <= aSP;
Set_BusB_To <= "1101";
when 2 =>
TStates <= "100";
Write <= '1';
IncDec_16 <= "1111";
Set_Addr_To <= aSP;
Set_BusB_To <= "1100";
when 3 =>
TStates <= "100";
Write <= '1';
when 4 =>
Inc_PC <= '1';
LDZ <= '1';
when 5 =>
Jump <= '1';
when others => null;
end case;
else
-- NOP
end if;
when "01110110" =>
-- HALT
Halt <= '1';
when "11110011" =>
-- DI
SetDI <= '1';
when "11111011" =>
-- EI
SetEI <= '1';
 
-- 16 BIT ARITHMETIC GROUP
when "00001001"|"00011001"|"00101001"|"00111001" =>
-- ADD HL,ss
MCycles <= "011";
case to_integer(unsigned(MCycle)) is
when 2 =>
NoRead <= '1';
ALU_Op <= "0000";
Read_To_Reg <= '1';
Save_ALU <= '1';
Set_BusA_To(2 downto 0) <= "101";
case to_integer(unsigned(IR(5 downto 4))) is
when 0|1|2 =>
Set_BusB_To(2 downto 1) <= IR(5 downto 4);
Set_BusB_To(0) <= '1';
when others =>
Set_BusB_To <= "1000";
end case;
TStates <= "100";
Arith16 <= '1';
when 3 =>
NoRead <= '1';
Read_To_Reg <= '1';
Save_ALU <= '1';
ALU_Op <= "0001";
Set_BusA_To(2 downto 0) <= "100";
case to_integer(unsigned(IR(5 downto 4))) is
when 0|1|2 =>
Set_BusB_To(2 downto 1) <= IR(5 downto 4);
when others =>
Set_BusB_To <= "1001";
end case;
Arith16 <= '1';
when others =>
end case;
when "00000011"|"00010011"|"00100011"|"00110011" =>
-- INC ss
TStates <= "110";
IncDec_16(3 downto 2) <= "01";
IncDec_16(1 downto 0) <= DPair;
when "00001011"|"00011011"|"00101011"|"00111011" =>
-- DEC ss
TStates <= "110";
IncDec_16(3 downto 2) <= "11";
IncDec_16(1 downto 0) <= DPair;
 
-- ROTATE AND SHIFT GROUP
when "00000111"
-- RLCA
|"00010111"
-- RLA
|"00001111"
-- RRCA
|"00011111" =>
-- RRA
Set_BusA_To(2 downto 0) <= "111";
ALU_Op <= "1000";
Read_To_Reg <= '1';
Save_ALU <= '1';
 
-- JUMP GROUP
when "11000011" =>
-- JP nn
MCycles <= "011";
case to_integer(unsigned(MCycle)) is
when 2 =>
Inc_PC <= '1';
LDZ <= '1';
when 3 =>
Inc_PC <= '1';
Jump <= '1';
when others => null;
end case;
when "11000010"|"11001010"|"11010010"|"11011010"|"11100010"|"11101010"|"11110010"|"11111010" =>
if IR(5) = '1' and Mode = 3 then
case IRB(4 downto 3) is
when "00" =>
-- LD ($FF00+C),A
MCycles <= "010";
case to_integer(unsigned(MCycle)) is
when 1 =>
Set_Addr_To <= aBC;
Set_BusB_To <= "0111";
when 2 =>
Write <= '1';
IORQ <= '1';
when others =>
end case;
when "01" =>
-- LD (nn),A
MCycles <= "100";
case to_integer(unsigned(MCycle)) is
when 2 =>
Inc_PC <= '1';
LDZ <= '1';
when 3 =>
Set_Addr_To <= aZI;
Inc_PC <= '1';
Set_BusB_To <= "0111";
when 4 =>
Write <= '1';
when others => null;
end case;
when "10" =>
-- LD A,($FF00+C)
MCycles <= "010";
case to_integer(unsigned(MCycle)) is
when 1 =>
Set_Addr_To <= aBC;
when 2 =>
Read_To_Acc <= '1';
IORQ <= '1';
when others =>
end case;
when "11" =>
-- LD A,(nn)
MCycles <= "100";
case to_integer(unsigned(MCycle)) is
when 2 =>
Inc_PC <= '1';
LDZ <= '1';
when 3 =>
Set_Addr_To <= aZI;
Inc_PC <= '1';
when 4 =>
Read_To_Acc <= '1';
when others => null;
end case;
end case;
else
-- JP cc,nn
MCycles <= "011";
case to_integer(unsigned(MCycle)) is
when 2 =>
Inc_PC <= '1';
LDZ <= '1';
when 3 =>
Inc_PC <= '1';
if is_cc_true(F, to_bitvector(IR(5 downto 3))) then
Jump <= '1';
end if;
when others => null;
end case;
end if;
when "00011000" =>
if Mode /= 2 then
-- JR e
MCycles <= "011";
case to_integer(unsigned(MCycle)) is
when 2 =>
Inc_PC <= '1';
when 3 =>
NoRead <= '1';
JumpE <= '1';
TStates <= "101";
when others => null;
end case;
end if;
when "00111000" =>
if Mode /= 2 then
-- JR C,e
MCycles <= "011";
case to_integer(unsigned(MCycle)) is
when 2 =>
Inc_PC <= '1';
if F(Flag_C) = '0' then
MCycles <= "010";
end if;
when 3 =>
NoRead <= '1';
JumpE <= '1';
TStates <= "101";
when others => null;
end case;
end if;
when "00110000" =>
if Mode /= 2 then
-- JR NC,e
MCycles <= "011";
case to_integer(unsigned(MCycle)) is
when 2 =>
Inc_PC <= '1';
if F(Flag_C) = '1' then
MCycles <= "010";
end if;
when 3 =>
NoRead <= '1';
JumpE <= '1';
TStates <= "101";
when others => null;
end case;
end if;
when "00101000" =>
if Mode /= 2 then
-- JR Z,e
MCycles <= "011";
case to_integer(unsigned(MCycle)) is
when 2 =>
Inc_PC <= '1';
if F(Flag_Z) = '0' then
MCycles <= "010";
end if;
when 3 =>
NoRead <= '1';
JumpE <= '1';
TStates <= "101";
when others => null;
end case;
end if;
when "00100000" =>
if Mode /= 2 then
-- JR NZ,e
MCycles <= "011";
case to_integer(unsigned(MCycle)) is
when 2 =>
Inc_PC <= '1';
if F(Flag_Z) = '1' then
MCycles <= "010";
end if;
when 3 =>
NoRead <= '1';
JumpE <= '1';
TStates <= "101";
when others => null;
end case;
end if;
when "11101001" =>
-- JP (HL)
JumpXY <= '1';
when "00010000" =>
if Mode = 3 then
I_DJNZ <= '1';
elsif Mode < 2 then
-- DJNZ,e
MCycles <= "011";
case to_integer(unsigned(MCycle)) is
when 1 =>
TStates <= "101";
I_DJNZ <= '1';
Set_BusB_To <= "1010";
Set_BusA_To(2 downto 0) <= "000";
Read_To_Reg <= '1';
Save_ALU <= '1';
ALU_Op <= "0010";
when 2 =>
I_DJNZ <= '1';
Inc_PC <= '1';
when 3 =>
NoRead <= '1';
JumpE <= '1';
TStates <= "101";
when others => null;
end case;
end if;
 
-- CALL AND RETURN GROUP
when "11001101" =>
-- CALL nn
MCycles <= "101";
case to_integer(unsigned(MCycle)) is
when 2 =>
Inc_PC <= '1';
LDZ <= '1';
when 3 =>
IncDec_16 <= "1111";
Inc_PC <= '1';
TStates <= "100";
Set_Addr_To <= aSP;
LDW <= '1';
Set_BusB_To <= "1101";
when 4 =>
Write <= '1';
IncDec_16 <= "1111";
Set_Addr_To <= aSP;
Set_BusB_To <= "1100";
when 5 =>
Write <= '1';
Call <= '1';
when others => null;
end case;
when "11000100"|"11001100"|"11010100"|"11011100"|"11100100"|"11101100"|"11110100"|"11111100" =>
if IR(5) = '0' or Mode /= 3 then
-- CALL cc,nn
MCycles <= "101";
case to_integer(unsigned(MCycle)) is
when 2 =>
Inc_PC <= '1';
LDZ <= '1';
when 3 =>
Inc_PC <= '1';
LDW <= '1';
if is_cc_true(F, to_bitvector(IR(5 downto 3))) then
IncDec_16 <= "1111";
Set_Addr_TO <= aSP;
TStates <= "100";
Set_BusB_To <= "1101";
else
MCycles <= "011";
end if;
when 4 =>
Write <= '1';
IncDec_16 <= "1111";
Set_Addr_To <= aSP;
Set_BusB_To <= "1100";
when 5 =>
Write <= '1';
Call <= '1';
when others => null;
end case;
end if;
when "11001001" =>
-- RET
MCycles <= "011";
case to_integer(unsigned(MCycle)) is
when 1 =>
TStates <= "101";
Set_Addr_TO <= aSP;
when 2 =>
IncDec_16 <= "0111";
Set_Addr_To <= aSP;
LDZ <= '1';
when 3 =>
Jump <= '1';
IncDec_16 <= "0111";
when others => null;
end case;
when "11000000"|"11001000"|"11010000"|"11011000"|"11100000"|"11101000"|"11110000"|"11111000" =>
if IR(5) = '1' and Mode = 3 then
case IRB(4 downto 3) is
when "00" =>
-- LD ($FF00+nn),A
MCycles <= "011";
case to_integer(unsigned(MCycle)) is
when 2 =>
Inc_PC <= '1';
Set_Addr_To <= aIOA;
Set_BusB_To <= "0111";
when 3 =>
Write <= '1';
when others => null;
end case;
when "01" =>
-- ADD SP,n
MCycles <= "011";
case to_integer(unsigned(MCycle)) is
when 2 =>
ALU_Op <= "0000";
Inc_PC <= '1';
Read_To_Reg <= '1';
Save_ALU <= '1';
Set_BusA_To <= "1000";
Set_BusB_To <= "0110";
when 3 =>
NoRead <= '1';
Read_To_Reg <= '1';
Save_ALU <= '1';
ALU_Op <= "0001";
Set_BusA_To <= "1001";
Set_BusB_To <= "1110"; -- Incorrect unsigned !!!!!!!!!!!!!!!!!!!!!
when others =>
end case;
when "10" =>
-- LD A,($FF00+nn)
MCycles <= "011";
case to_integer(unsigned(MCycle)) is
when 2 =>
Inc_PC <= '1';
Set_Addr_To <= aIOA;
when 3 =>
Read_To_Acc <= '1';
when others => null;
end case;
when "11" =>
-- LD HL,SP+n -- Not correct !!!!!!!!!!!!!!!!!!!
MCycles <= "101";
case to_integer(unsigned(MCycle)) is
when 2 =>
Inc_PC <= '1';
LDZ <= '1';
when 3 =>
Set_Addr_To <= aZI;
Inc_PC <= '1';
LDW <= '1';
when 4 =>
Set_BusA_To(2 downto 0) <= "101"; -- L
Read_To_Reg <= '1';
Inc_WZ <= '1';
Set_Addr_To <= aZI;
when 5 =>
Set_BusA_To(2 downto 0) <= "100"; -- H
Read_To_Reg <= '1';
when others => null;
end case;
end case;
else
-- RET cc
MCycles <= "011";
case to_integer(unsigned(MCycle)) is
when 1 =>
if is_cc_true(F, to_bitvector(IR(5 downto 3))) then
Set_Addr_TO <= aSP;
else
MCycles <= "001";
end if;
TStates <= "101";
when 2 =>
IncDec_16 <= "0111";
Set_Addr_To <= aSP;
LDZ <= '1';
when 3 =>
Jump <= '1';
IncDec_16 <= "0111";
when others => null;
end case;
end if;
when "11000111"|"11001111"|"11010111"|"11011111"|"11100111"|"11101111"|"11110111"|"11111111" =>
-- RST p
MCycles <= "011";
case to_integer(unsigned(MCycle)) is
when 1 =>
TStates <= "101";
IncDec_16 <= "1111";
Set_Addr_To <= aSP;
Set_BusB_To <= "1101";
when 2 =>
Write <= '1';
IncDec_16 <= "1111";
Set_Addr_To <= aSP;
Set_BusB_To <= "1100";
when 3 =>
Write <= '1';
RstP <= '1';
when others => null;
end case;
 
-- INPUT AND OUTPUT GROUP
when "11011011" =>
if Mode /= 3 then
-- IN A,(n)
MCycles <= "011";
case to_integer(unsigned(MCycle)) is
when 2 =>
Inc_PC <= '1';
Set_Addr_To <= aIOA;
when 3 =>
Read_To_Acc <= '1';
IORQ <= '1';
when others => null;
end case;
end if;
when "11010011" =>
if Mode /= 3 then
-- OUT (n),A
MCycles <= "011";
case to_integer(unsigned(MCycle)) is
when 2 =>
Inc_PC <= '1';
Set_Addr_To <= aIOA;
Set_BusB_To <= "0111";
when 3 =>
Write <= '1';
IORQ <= '1';
when others => null;
end case;
end if;
 
------------------------------------------------------------------------------
------------------------------------------------------------------------------
-- MULTIBYTE INSTRUCTIONS
------------------------------------------------------------------------------
------------------------------------------------------------------------------
 
when "11001011" =>
if Mode /= 2 then
Prefix <= "01";
end if;
 
when "11101101" =>
if Mode < 2 then
Prefix <= "10";
end if;
 
when "11011101"|"11111101" =>
if Mode < 2 then
Prefix <= "11";
end if;
 
end case;
 
when "01" =>
 
------------------------------------------------------------------------------
--
-- CB prefixed instructions
--
------------------------------------------------------------------------------
 
Set_BusA_To(2 downto 0) <= IR(2 downto 0);
Set_BusB_To(2 downto 0) <= IR(2 downto 0);
 
case IRB is
when "00000000"|"00000001"|"00000010"|"00000011"|"00000100"|"00000101"|"00000111"
|"00010000"|"00010001"|"00010010"|"00010011"|"00010100"|"00010101"|"00010111"
|"00001000"|"00001001"|"00001010"|"00001011"|"00001100"|"00001101"|"00001111"
|"00011000"|"00011001"|"00011010"|"00011011"|"00011100"|"00011101"|"00011111"
|"00100000"|"00100001"|"00100010"|"00100011"|"00100100"|"00100101"|"00100111"
|"00101000"|"00101001"|"00101010"|"00101011"|"00101100"|"00101101"|"00101111"
|"00110000"|"00110001"|"00110010"|"00110011"|"00110100"|"00110101"|"00110111"
|"00111000"|"00111001"|"00111010"|"00111011"|"00111100"|"00111101"|"00111111" =>
-- RLC r
-- RL r
-- RRC r
-- RR r
-- SLA r
-- SRA r
-- SRL r
-- SLL r (Undocumented) / SWAP r
if MCycle = "001" then
ALU_Op <= "1000";
Read_To_Reg <= '1';
Save_ALU <= '1';
end if;
when "00000110"|"00010110"|"00001110"|"00011110"|"00101110"|"00111110"|"00100110"|"00110110" =>
-- RLC (HL)
-- RL (HL)
-- RRC (HL)
-- RR (HL)
-- SRA (HL)
-- SRL (HL)
-- SLA (HL)
-- SLL (HL) (Undocumented) / SWAP (HL)
MCycles <= "011";
case to_integer(unsigned(MCycle)) is
when 1 | 7 =>
Set_Addr_To <= aXY;
when 2 =>
ALU_Op <= "1000";
Read_To_Reg <= '1';
Save_ALU <= '1';
Set_Addr_To <= aXY;
TStates <= "100";
when 3 =>
Write <= '1';
when others =>
end case;
when "01000000"|"01000001"|"01000010"|"01000011"|"01000100"|"01000101"|"01000111"
|"01001000"|"01001001"|"01001010"|"01001011"|"01001100"|"01001101"|"01001111"
|"01010000"|"01010001"|"01010010"|"01010011"|"01010100"|"01010101"|"01010111"
|"01011000"|"01011001"|"01011010"|"01011011"|"01011100"|"01011101"|"01011111"
|"01100000"|"01100001"|"01100010"|"01100011"|"01100100"|"01100101"|"01100111"
|"01101000"|"01101001"|"01101010"|"01101011"|"01101100"|"01101101"|"01101111"
|"01110000"|"01110001"|"01110010"|"01110011"|"01110100"|"01110101"|"01110111"
|"01111000"|"01111001"|"01111010"|"01111011"|"01111100"|"01111101"|"01111111" =>
-- BIT b,r
if MCycle = "001" then
Set_BusB_To(2 downto 0) <= IR(2 downto 0);
ALU_Op <= "1001";
end if;
when "01000110"|"01001110"|"01010110"|"01011110"|"01100110"|"01101110"|"01110110"|"01111110" =>
-- BIT b,(HL)
MCycles <= "010";
case to_integer(unsigned(MCycle)) is
when 1 | 7 =>
Set_Addr_To <= aXY;
when 2 =>
ALU_Op <= "1001";
TStates <= "100";
when others =>
end case;
when "11000000"|"11000001"|"11000010"|"11000011"|"11000100"|"11000101"|"11000111"
|"11001000"|"11001001"|"11001010"|"11001011"|"11001100"|"11001101"|"11001111"
|"11010000"|"11010001"|"11010010"|"11010011"|"11010100"|"11010101"|"11010111"
|"11011000"|"11011001"|"11011010"|"11011011"|"11011100"|"11011101"|"11011111"
|"11100000"|"11100001"|"11100010"|"11100011"|"11100100"|"11100101"|"11100111"
|"11101000"|"11101001"|"11101010"|"11101011"|"11101100"|"11101101"|"11101111"
|"11110000"|"11110001"|"11110010"|"11110011"|"11110100"|"11110101"|"11110111"
|"11111000"|"11111001"|"11111010"|"11111011"|"11111100"|"11111101"|"11111111" =>
-- SET b,r
if MCycle = "001" then
ALU_Op <= "1010";
Read_To_Reg <= '1';
Save_ALU <= '1';
end if;
when "11000110"|"11001110"|"11010110"|"11011110"|"11100110"|"11101110"|"11110110"|"11111110" =>
-- SET b,(HL)
MCycles <= "011";
case to_integer(unsigned(MCycle)) is
when 1 | 7 =>
Set_Addr_To <= aXY;
when 2 =>
ALU_Op <= "1010";
Read_To_Reg <= '1';
Save_ALU <= '1';
Set_Addr_To <= aXY;
TStates <= "100";
when 3 =>
Write <= '1';
when others =>
end case;
when "10000000"|"10000001"|"10000010"|"10000011"|"10000100"|"10000101"|"10000111"
|"10001000"|"10001001"|"10001010"|"10001011"|"10001100"|"10001101"|"10001111"
|"10010000"|"10010001"|"10010010"|"10010011"|"10010100"|"10010101"|"10010111"
|"10011000"|"10011001"|"10011010"|"10011011"|"10011100"|"10011101"|"10011111"
|"10100000"|"10100001"|"10100010"|"10100011"|"10100100"|"10100101"|"10100111"
|"10101000"|"10101001"|"10101010"|"10101011"|"10101100"|"10101101"|"10101111"
|"10110000"|"10110001"|"10110010"|"10110011"|"10110100"|"10110101"|"10110111"
|"10111000"|"10111001"|"10111010"|"10111011"|"10111100"|"10111101"|"10111111" =>
-- RES b,r
if MCycle = "001" then
ALU_Op <= "1011";
Read_To_Reg <= '1';
Save_ALU <= '1';
end if;
when "10000110"|"10001110"|"10010110"|"10011110"|"10100110"|"10101110"|"10110110"|"10111110" =>
-- RES b,(HL)
MCycles <= "011";
case to_integer(unsigned(MCycle)) is
when 1 | 7 =>
Set_Addr_To <= aXY;
when 2 =>
ALU_Op <= "1011";
Read_To_Reg <= '1';
Save_ALU <= '1';
Set_Addr_To <= aXY;
TStates <= "100";
when 3 =>
Write <= '1';
when others =>
end case;
end case;
 
when others =>
 
------------------------------------------------------------------------------
--
-- ED prefixed instructions
--
------------------------------------------------------------------------------
 
case IRB is
when "00000000"|"00000001"|"00000010"|"00000011"|"00000100"|"00000101"|"00000110"|"00000111"
|"00001000"|"00001001"|"00001010"|"00001011"|"00001100"|"00001101"|"00001110"|"00001111"
|"00010000"|"00010001"|"00010010"|"00010011"|"00010100"|"00010101"|"00010110"|"00010111"
|"00011000"|"00011001"|"00011010"|"00011011"|"00011100"|"00011101"|"00011110"|"00011111"
|"00100000"|"00100001"|"00100010"|"00100011"|"00100100"|"00100101"|"00100110"|"00100111"
|"00101000"|"00101001"|"00101010"|"00101011"|"00101100"|"00101101"|"00101110"|"00101111"
|"00110000"|"00110001"|"00110010"|"00110011"|"00110100"|"00110101"|"00110110"|"00110111"
|"00111000"|"00111001"|"00111010"|"00111011"|"00111100"|"00111101"|"00111110"|"00111111"
 
 
|"10000000"|"10000001"|"10000010"|"10000011"|"10000100"|"10000101"|"10000110"|"10000111"
|"10001000"|"10001001"|"10001010"|"10001011"|"10001100"|"10001101"|"10001110"|"10001111"
|"10010000"|"10010001"|"10010010"|"10010011"|"10010100"|"10010101"|"10010110"|"10010111"
|"10011000"|"10011001"|"10011010"|"10011011"|"10011100"|"10011101"|"10011110"|"10011111"
| "10100100"|"10100101"|"10100110"|"10100111"
| "10101100"|"10101101"|"10101110"|"10101111"
| "10110100"|"10110101"|"10110110"|"10110111"
| "10111100"|"10111101"|"10111110"|"10111111"
|"11000000"|"11000001"|"11000010"|"11000011"|"11000100"|"11000101"|"11000110"|"11000111"
|"11001000"|"11001001"|"11001010"|"11001011"|"11001100"|"11001101"|"11001110"|"11001111"
|"11010000"|"11010001"|"11010010"|"11010011"|"11010100"|"11010101"|"11010110"|"11010111"
|"11011000"|"11011001"|"11011010"|"11011011"|"11011100"|"11011101"|"11011110"|"11011111"
|"11100000"|"11100001"|"11100010"|"11100011"|"11100100"|"11100101"|"11100110"|"11100111"
|"11101000"|"11101001"|"11101010"|"11101011"|"11101100"|"11101101"|"11101110"|"11101111"
|"11110000"|"11110001"|"11110010"|"11110011"|"11110100"|"11110101"|"11110110"|"11110111"
|"11111000"|"11111001"|"11111010"|"11111011"|"11111100"|"11111101"|"11111110"|"11111111" =>
null; -- NOP, undocumented
when "01111110"|"01111111" =>
-- NOP, undocumented
null;
-- 8 BIT LOAD GROUP
when "01010111" =>
-- LD A,I
Special_LD <= "100";
TStates <= "101";
when "01011111" =>
-- LD A,R
Special_LD <= "101";
TStates <= "101";
when "01000111" =>
-- LD I,A
Special_LD <= "110";
TStates <= "101";
when "01001111" =>
-- LD R,A
Special_LD <= "111";
TStates <= "101";
-- 16 BIT LOAD GROUP
when "01001011"|"01011011"|"01101011"|"01111011" =>
-- LD dd,(nn)
MCycles <= "101";
case to_integer(unsigned(MCycle)) is
when 2 =>
Inc_PC <= '1';
LDZ <= '1';
when 3 =>
Set_Addr_To <= aZI;
Inc_PC <= '1';
LDW <= '1';
when 4 =>
Read_To_Reg <= '1';
if IR(5 downto 4) = "11" then
Set_BusA_To <= "1000";
else
Set_BusA_To(2 downto 1) <= IR(5 downto 4);
Set_BusA_To(0) <= '1';
end if;
Inc_WZ <= '1';
Set_Addr_To <= aZI;
when 5 =>
Read_To_Reg <= '1';
if IR(5 downto 4) = "11" then
Set_BusA_To <= "1001";
else
Set_BusA_To(2 downto 1) <= IR(5 downto 4);
Set_BusA_To(0) <= '0';
end if;
when others => null;
end case;
when "01000011"|"01010011"|"01100011"|"01110011" =>
-- LD (nn),dd
MCycles <= "101";
case to_integer(unsigned(MCycle)) is
when 2 =>
Inc_PC <= '1';
LDZ <= '1';
when 3 =>
Set_Addr_To <= aZI;
Inc_PC <= '1';
LDW <= '1';
if IR(5 downto 4) = "11" then
Set_BusB_To <= "1000";
else
Set_BusB_To(2 downto 1) <= IR(5 downto 4);
Set_BusB_To(0) <= '1';
Set_BusB_To(3) <= '0';
end if;
when 4 =>
Inc_WZ <= '1';
Set_Addr_To <= aZI;
Write <= '1';
if IR(5 downto 4) = "11" then
Set_BusB_To <= "1001";
else
Set_BusB_To(2 downto 1) <= IR(5 downto 4);
Set_BusB_To(0) <= '0';
Set_BusB_To(3) <= '0';
end if;
when 5 =>
Write <= '1';
when others => null;
end case;
when "10100000" | "10101000" | "10110000" | "10111000" =>
-- LDI, LDD, LDIR, LDDR
MCycles <= "100";
case to_integer(unsigned(MCycle)) is
when 1 =>
Set_Addr_To <= aXY;
IncDec_16 <= "1100"; -- BC
when 2 =>
Set_BusB_To <= "0110";
Set_BusA_To(2 downto 0) <= "111";
ALU_Op <= "0000";
Set_Addr_To <= aDE;
if IR(3) = '0' then
IncDec_16 <= "0110"; -- IX
else
IncDec_16 <= "1110";
end if;
when 3 =>
I_BT <= '1';
TStates <= "101";
Write <= '1';
if IR(3) = '0' then
IncDec_16 <= "0101"; -- DE
else
IncDec_16 <= "1101";
end if;
when 4 =>
NoRead <= '1';
TStates <= "101";
when others => null;
end case;
when "10100001" | "10101001" | "10110001" | "10111001" =>
-- CPI, CPD, CPIR, CPDR
MCycles <= "100";
case to_integer(unsigned(MCycle)) is
when 1 =>
Set_Addr_To <= aXY;
IncDec_16 <= "1100"; -- BC
when 2 =>
Set_BusB_To <= "0110";
Set_BusA_To(2 downto 0) <= "111";
ALU_Op <= "0111";
Save_ALU <= '1';
PreserveC <= '1';
if IR(3) = '0' then
IncDec_16 <= "0110";
else
IncDec_16 <= "1110";
end if;
when 3 =>
NoRead <= '1';
I_BC <= '1';
TStates <= "101";
when 4 =>
NoRead <= '1';
TStates <= "101";
when others => null;
end case;
when "01000100"|"01001100"|"01010100"|"01011100"|"01100100"|"01101100"|"01110100"|"01111100" =>
-- NEG
Alu_OP <= "0010";
Set_BusB_To <= "0111";
Set_BusA_To <= "1010";
Read_To_Acc <= '1';
Save_ALU <= '1';
when "01000110"|"01001110"|"01100110"|"01101110" =>
-- IM 0
IMode <= "00";
when "01010110"|"01110110" =>
-- IM 1
IMode <= "01";
when "01011110"|"01110111" =>
-- IM 2
IMode <= "10";
-- 16 bit arithmetic
when "01001010"|"01011010"|"01101010"|"01111010" =>
-- ADC HL,ss
MCycles <= "011";
case to_integer(unsigned(MCycle)) is
when 2 =>
NoRead <= '1';
ALU_Op <= "0001";
Read_To_Reg <= '1';
Save_ALU <= '1';
Set_BusA_To(2 downto 0) <= "101";
case to_integer(unsigned(IR(5 downto 4))) is
when 0|1|2 =>
Set_BusB_To(2 downto 1) <= IR(5 downto 4);
Set_BusB_To(0) <= '1';
when others =>
Set_BusB_To <= "1000";
end case;
TStates <= "100";
when 3 =>
NoRead <= '1';
Read_To_Reg <= '1';
Save_ALU <= '1';
ALU_Op <= "0001";
Set_BusA_To(2 downto 0) <= "100";
case to_integer(unsigned(IR(5 downto 4))) is
when 0|1|2 =>
Set_BusB_To(2 downto 1) <= IR(5 downto 4);
Set_BusB_To(0) <= '0';
when others =>
Set_BusB_To <= "1001";
end case;
when others =>
end case;
when "01000010"|"01010010"|"01100010"|"01110010" =>
-- SBC HL,ss
MCycles <= "011";
case to_integer(unsigned(MCycle)) is
when 2 =>
NoRead <= '1';
ALU_Op <= "0011";
Read_To_Reg <= '1';
Save_ALU <= '1';
Set_BusA_To(2 downto 0) <= "101";
case to_integer(unsigned(IR(5 downto 4))) is
when 0|1|2 =>
Set_BusB_To(2 downto 1) <= IR(5 downto 4);
Set_BusB_To(0) <= '1';
when others =>
Set_BusB_To <= "1000";
end case;
TStates <= "100";
when 3 =>
NoRead <= '1';
ALU_Op <= "0011";
Read_To_Reg <= '1';
Save_ALU <= '1';
Set_BusA_To(2 downto 0) <= "100";
case to_integer(unsigned(IR(5 downto 4))) is
when 0|1|2 =>
Set_BusB_To(2 downto 1) <= IR(5 downto 4);
when others =>
Set_BusB_To <= "1001";
end case;
when others =>
end case;
when "01101111" =>
-- RLD
MCycles <= "100";
case to_integer(unsigned(MCycle)) is
when 2 =>
NoRead <= '1';
Set_Addr_To <= aXY;
when 3 =>
Read_To_Reg <= '1';
Set_BusB_To(2 downto 0) <= "110";
Set_BusA_To(2 downto 0) <= "111";
ALU_Op <= "1101";
TStates <= "100";
Set_Addr_To <= aXY;
Save_ALU <= '1';
when 4 =>
I_RLD <= '1';
Write <= '1';
when others =>
end case;
when "01100111" =>
-- RRD
MCycles <= "100";
case to_integer(unsigned(MCycle)) is
when 2 =>
Set_Addr_To <= aXY;
when 3 =>
Read_To_Reg <= '1';
Set_BusB_To(2 downto 0) <= "110";
Set_BusA_To(2 downto 0) <= "111";
ALU_Op <= "1110";
TStates <= "100";
Set_Addr_To <= aXY;
Save_ALU <= '1';
when 4 =>
I_RRD <= '1';
Write <= '1';
when others =>
end case;
when "01000101"|"01001101"|"01010101"|"01011101"|"01100101"|"01101101"|"01110101"|"01111101" =>
-- RETI, RETN
MCycles <= "011";
case to_integer(unsigned(MCycle)) is
when 1 =>
Set_Addr_TO <= aSP;
when 2 =>
IncDec_16 <= "0111";
Set_Addr_To <= aSP;
LDZ <= '1';
when 3 =>
Jump <= '1';
IncDec_16 <= "0111";
I_RETN <= '1';
when others => null;
end case;
when "01000000"|"01001000"|"01010000"|"01011000"|"01100000"|"01101000"|"01110000"|"01111000" =>
-- IN r,(C)
MCycles <= "010";
case to_integer(unsigned(MCycle)) is
when 1 =>
Set_Addr_To <= aBC;
when 2 =>
IORQ <= '1';
if IR(5 downto 3) /= "110" then
Read_To_Reg <= '1';
Set_BusA_To(2 downto 0) <= IR(5 downto 3);
end if;
I_INRC <= '1';
when others =>
end case;
when "01000001"|"01001001"|"01010001"|"01011001"|"01100001"|"01101001"|"01110001"|"01111001" =>
-- OUT (C),r
-- OUT (C),0
MCycles <= "010";
case to_integer(unsigned(MCycle)) is
when 1 =>
Set_Addr_To <= aBC;
Set_BusB_To(2 downto 0) <= IR(5 downto 3);
if IR(5 downto 3) = "110" then
Set_BusB_To(3) <= '1';
end if;
when 2 =>
Write <= '1';
IORQ <= '1';
when others =>
end case;
when "10100010" | "10101010" | "10110010" | "10111010" =>
-- INI, IND, INIR, INDR
MCycles <= "100";
case to_integer(unsigned(MCycle)) is
when 1 =>
Set_Addr_To <= aBC;
Set_BusB_To <= "1010";
Set_BusA_To <= "0000";
Read_To_Reg <= '1';
Save_ALU <= '1';
ALU_Op <= "0010";
when 2 =>
IORQ <= '1';
Set_BusB_To <= "0110";
Set_Addr_To <= aXY;
when 3 =>
if IR(3) = '0' then
IncDec_16 <= "0010";
else
IncDec_16 <= "1010";
end if;
TStates <= "100";
Write <= '1';
I_BTR <= '1';
when 4 =>
NoRead <= '1';
TStates <= "101";
when others => null;
end case;
when "10100011" | "10101011" | "10110011" | "10111011" =>
-- OUTI, OUTD, OTIR, OTDR
MCycles <= "100";
case to_integer(unsigned(MCycle)) is
when 1 =>
TStates <= "101";
Set_Addr_To <= aXY;
Set_BusB_To <= "1010";
Set_BusA_To <= "0000";
Read_To_Reg <= '1';
Save_ALU <= '1';
ALU_Op <= "0010";
when 2 =>
Set_BusB_To <= "0110";
Set_Addr_To <= aBC;
when 3 =>
if IR(3) = '0' then
IncDec_16 <= "0010";
else
IncDec_16 <= "1010";
end if;
IORQ <= '1';
Write <= '1';
I_BTR <= '1';
when 4 =>
NoRead <= '1';
TStates <= "101";
when others => null;
end case;
end case;
 
end case;
 
if Mode = 1 then
if MCycle = "001" then
-- TStates <= "100";
else
TStates <= "011";
end if;
end if;
 
if Mode = 3 then
if MCycle = "001" then
-- TStates <= "100";
else
TStates <= "100";
end if;
end if;
 
if Mode < 2 then
if MCycle = "110" then
Inc_PC <= '1';
if Mode = 1 then
Set_Addr_To <= aXY;
TStates <= "100";
Set_BusB_To(2 downto 0) <= SSS;
Set_BusB_To(3) <= '0';
end if;
if IRB = "00110110" or IRB = "11001011" then
Set_Addr_To <= aNone;
end if;
end if;
if MCycle = "111" then
if Mode = 0 then
TStates <= "101";
end if;
if ISet /= "01" then
Set_Addr_To <= aXY;
end if;
Set_BusB_To(2 downto 0) <= SSS;
Set_BusB_To(3) <= '0';
if IRB = "00110110" or ISet = "01" then
-- LD (HL),n
Inc_PC <= '1';
else
NoRead <= '1';
end if;
end if;
end if;
 
end process;
 
end;
/VHDL/t80/SSRAM.vhd
0,0 → 1,92
--
-- Inferrable Synchronous SRAM for XST synthesis
--
-- Version : 0220
--
-- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org)
--
-- All rights reserved
--
-- Redistribution and use in source and synthezised forms, with or without
-- modification, are permitted provided that the following conditions are met:
--
-- Redistributions of source code must retain the above copyright notice,
-- this list of conditions and the following disclaimer.
--
-- Redistributions in synthesized form must reproduce the above copyright
-- notice, this list of conditions and the following disclaimer in the
-- documentation and/or other materials provided with the distribution.
--
-- Neither the name of the author nor the names of other contributors may
-- be used to endorse or promote products derived from this software without
-- specific prior written permission.
--
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-- POSSIBILITY OF SUCH DAMAGE.
--
-- Please report bugs to the author, but before you do so, please
-- make sure that this is not a derivative work and that
-- you have the latest version of this file.
--
-- The latest version of this file can be found at:
-- http://www.opencores.org/cvsweb.shtml/t51/
--
-- Limitations :
--
-- File history :
-- 0208 : Initial release
-- 0218 : Fixed data out at write
-- 0220 : Added support for XST
 
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
 
entity SSRAM is
generic(
AddrWidth : integer := 11;
DataWidth : integer := 8
);
port(
Clk : in std_logic;
CE_n : in std_logic;
WE_n : in std_logic;
A : in std_logic_vector(AddrWidth - 1 downto 0);
DIn : in std_logic_vector(DataWidth - 1 downto 0);
DOut : out std_logic_vector(DataWidth - 1 downto 0)
);
end SSRAM;
 
architecture behaviour of SSRAM is
 
type Memory_Image is array (natural range <>) of std_logic_vector(DataWidth - 1 downto 0);
signal RAM : Memory_Image(0 to 2 ** AddrWidth - 1);
signal A_r : std_logic_vector(AddrWidth - 1 downto 0);
 
begin
 
process (Clk)
begin
if Clk'event and Clk = '1' then
if (CE_n nor WE_n) = '1' then
RAM(to_integer(unsigned(A))) <= DIn;
end if;
A_r <= A;
end if;
end process;
 
DOut <= RAM(to_integer(unsigned(A_r)))
-- pragma translate_off
when not is_x(A_r) else (others => '-')
-- pragma translate_on
;
end;
/VHDL/t80/T80s.vhd.bak
0,0 → 1,190
--
-- Z80 compatible microprocessor core, synchronous top level
-- Different timing than the original z80
-- Inputs needs to be synchronous and outputs may glitch
--
-- Version : 0242
--
-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org)
--
-- All rights reserved
--
-- Redistribution and use in source and synthezised forms, with or without
-- modification, are permitted provided that the following conditions are met:
--
-- Redistributions of source code must retain the above copyright notice,
-- this list of conditions and the following disclaimer.
--
-- Redistributions in synthesized form must reproduce the above copyright
-- notice, this list of conditions and the following disclaimer in the
-- documentation and/or other materials provided with the distribution.
--
-- Neither the name of the author nor the names of other contributors may
-- be used to endorse or promote products derived from this software without
-- specific prior written permission.
--
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-- POSSIBILITY OF SUCH DAMAGE.
--
-- Please report bugs to the author, but before you do so, please
-- make sure that this is not a derivative work and that
-- you have the latest version of this file.
--
-- The latest version of this file can be found at:
-- http://www.opencores.org/cvsweb.shtml/t80/
--
-- Limitations :
--
-- File history :
--
-- 0208 : First complete release
--
-- 0210 : Fixed read with wait
--
-- 0211 : Fixed interrupt cycle
--
-- 0235 : Updated for T80 interface change
--
-- 0236 : Added T2Write generic
--
-- 0237 : Fixed T2Write with wait state
--
-- 0238 : Updated for T80 interface change
--
-- 0240 : Updated for T80 interface change
--
-- 0242 : Updated for T80 interface change
--
 
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use work.T80_Pack.all;
 
entity T80s is
generic(
Mode : integer := 0; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB
T2Write : integer := 0; -- 0 => WR_n active in T3, /=0 => WR_n active in T2
IOWait : integer := 1 -- 0 => Single cycle I/O, 1 => Std I/O cycle
);
port(
RESET_n : in std_logic;
CLK_n : in std_logic;
WAIT_n : in std_logic;
INT_n : in std_logic;
NMI_n : in std_logic;
BUSRQ_n : in std_logic;
M1_n : out std_logic;
MREQ_n : out std_logic;
IORQ_n : out std_logic;
RD_n : out std_logic;
WR_n : out std_logic;
RFSH_n : out std_logic;
HALT_n : out std_logic;
BUSAK_n : out std_logic;
A : out std_logic_vector(15 downto 0);
DI : in std_logic_vector(7 downto 0);
DO : out std_logic_vector(7 downto 0)
);
end T80s;
 
architecture rtl of T80s is
 
signal CEN : std_logic;
signal IntCycle_n : std_logic;
signal NoRead : std_logic;
signal Write : std_logic;
signal IORQ : std_logic;
signal DI_Reg : std_logic_vector(7 downto 0);
signal MCycle : std_logic_vector(2 downto 0);
signal TState : std_logic_vector(2 downto 0);
 
begin
 
CEN <= '1';
 
u0 : T80
generic map(
Mode => Mode,
IOWait => IOWait)
port map(
CEN => CEN,
M1_n => M1_n,
IORQ => IORQ,
NoRead => NoRead,
Write => Write,
RFSH_n => RFSH_n,
HALT_n => HALT_n,
WAIT_n => Wait_n,
INT_n => INT_n,
NMI_n => NMI_n,
RESET_n => RESET_n,
BUSRQ_n => BUSRQ_n,
BUSAK_n => BUSAK_n,
CLK_n => CLK_n,
A => A,
DInst => DI,
DI => DI_Reg,
DO => DO,
MC => MCycle,
TS => TState,
IntCycle_n => IntCycle_n);
 
process (RESET_n, CLK_n)
begin
if RESET_n = '0' then
RD_n <= '1';
WR_n <= '1';
IORQ_n <= '1';
MREQ_n <= '1';
DI_Reg <= "00000000";
elsif CLK_n'event and CLK_n = '1' then
RD_n <= '1';
WR_n <= '1';
IORQ_n <= '1';
MREQ_n <= '1';
if MCycle = "001" then
if TState = "001" or (TState = "010" and Wait_n = '0') then
RD_n <= not IntCycle_n;
MREQ_n <= not IntCycle_n;
IORQ_n <= IntCycle_n;
end if;
if TState = "011" then
MREQ_n <= '0';
end if;
else
if (TState = "001" or (TState = "010" and Wait_n = '0')) and NoRead = '0' and Write = '0' then
RD_n <= '0';
IORQ_n <= not IORQ;
MREQ_n <= IORQ;
end if;
if T2Write = 0 then
if TState = "010" and Write = '1' then
WR_n <= '0';
IORQ_n <= not IORQ;
MREQ_n <= IORQ;
end if;
else
if (TState = "001" or (TState = "010" and Wait_n = '0')) and Write = '1' then
WR_n <= '0';
IORQ_n <= not IORQ;
MREQ_n <= IORQ;
end if;
end if;
end if;
if TState = "010" and Wait_n = '1' then
DI_Reg <= DI;
end if;
end if;
end process;
 
end;
/VHDL/t80/DebugSystem.vhd
0,0 → 1,181
-- Z80, Monitor ROM, 4k RAM and two 16450 UARTs
-- that can be synthesized and used with
-- the NoICE debugger that can be found at
-- http://www.noicedebugger.com/
 
library IEEE;
use IEEE.std_logic_1164.all;
 
entity DebugSystem is
port(
Reset_n : in std_logic;
Clk : in std_logic;
NMI_n : in std_logic;
RXD0 : in std_logic;
CTS0 : in std_logic;
DSR0 : in std_logic;
RI0 : in std_logic;
DCD0 : in std_logic;
RXD1 : in std_logic;
CTS1 : in std_logic;
DSR1 : in std_logic;
RI1 : in std_logic;
DCD1 : in std_logic;
TXD0 : out std_logic;
RTS0 : out std_logic;
DTR0 : out std_logic;
TXD1 : out std_logic;
RTS1 : out std_logic;
DTR1 : out std_logic
);
end DebugSystem;
 
architecture struct of DebugSystem is
 
signal M1_n : std_logic;
signal MREQ_n : std_logic;
signal IORQ_n : std_logic;
signal RD_n : std_logic;
signal WR_n : std_logic;
signal RFSH_n : std_logic;
signal HALT_n : std_logic;
signal WAIT_n : std_logic;
signal INT_n : std_logic;
signal RESET_s : std_logic;
signal BUSRQ_n : std_logic;
signal BUSAK_n : std_logic;
signal A : std_logic_vector(15 downto 0);
signal D : std_logic_vector(7 downto 0);
signal ROM_D : std_logic_vector(7 downto 0);
signal SRAM_D : std_logic_vector(7 downto 0);
signal UART0_D : std_logic_vector(7 downto 0);
signal UART1_D : std_logic_vector(7 downto 0);
signal CPU_D : std_logic_vector(7 downto 0);
 
signal Mirror : std_logic;
 
signal IOWR_n : std_logic;
signal RAMCS_n : std_logic;
signal UART0CS_n : std_logic;
signal UART1CS_n : std_logic;
 
signal BaudOut0 : std_logic;
signal BaudOut1 : std_logic;
 
begin
 
Wait_n <= '1';
BusRq_n <= '1';
INT_n <= '1';
 
process (Reset_n, Clk)
begin
if Reset_n = '0' then
Reset_s <= '0';
Mirror <= '0';
elsif Clk'event and Clk = '1' then
Reset_s <= '1';
if IORQ_n = '0' and A(7 downto 4) = "1111" then
Mirror <= D(0);
end if;
end if;
end process;
 
IOWR_n <= WR_n or IORQ_n;
RAMCS_n <= (not Mirror and not A(15)) or MREQ_n;
UART0CS_n <= '0' when IORQ_n = '0' and A(7 downto 3) = "00000" else '1';
UART1CS_n <= '0' when IORQ_n = '0' and A(7 downto 3) = "10000" else '1';
 
CPU_D <=
SRAM_D when RAMCS_n = '0' else
UART0_D when UART0CS_n = '0' else
UART1_D when UART1CS_n = '0' else
ROM_D;
 
u0 : entity work.T80s
generic map(Mode => 1, T2Write => 1, IOWait => 0)
port map(
RESET_n => RESET_s,
CLK_n => Clk,
WAIT_n => WAIT_n,
INT_n => INT_n,
NMI_n => NMI_n,
BUSRQ_n => BUSRQ_n,
M1_n => M1_n,
MREQ_n => MREQ_n,
IORQ_n => IORQ_n,
RD_n => RD_n,
WR_n => WR_n,
RFSH_n => RFSH_n,
HALT_n => HALT_n,
BUSAK_n => BUSAK_n,
A => A,
DI => CPU_D,
DO => D);
 
u1 : entity work.MonZ80
port map(
Clk => Clk,
A => A(10 downto 0),
D => ROM_D);
 
u2 : entity work.SSRAM
generic map(
AddrWidth => 12)
port map(
Clk => Clk,
CE_n => RAMCS_n,
WE_n => WR_n,
A => A(11 downto 0),
DIn => D,
DOut => SRAM_D);
 
u3 : entity work.T16450
port map(
MR_n => Reset_s,
XIn => Clk,
RClk => BaudOut0,
CS_n => UART0CS_n,
Rd_n => RD_n,
Wr_n => IOWR_n,
A => A(2 downto 0),
D_In => D,
D_Out => UART0_D,
SIn => RXD0,
CTS_n => CTS0,
DSR_n => DSR0,
RI_n => RI0,
DCD_n => DCD0,
SOut => TXD0,
RTS_n => RTS0,
DTR_n => DTR0,
OUT1_n => open,
OUT2_n => open,
BaudOut => BaudOut0,
Intr => open);
 
u4 : entity work.T16450
port map(
MR_n => Reset_s,
XIn => Clk,
RClk => BaudOut1,
CS_n => UART1CS_n,
Rd_n => RD_n,
Wr_n => IOWR_n,
A => A(2 downto 0),
D_In => D,
D_Out => UART1_D,
SIn => RXD1,
CTS_n => CTS1,
DSR_n => DSR1,
RI_n => RI1,
DCD_n => DCD1,
SOut => TXD1,
RTS_n => RTS1,
DTR_n => DTR1,
OUT1_n => open,
OUT2_n => open,
BaudOut => BaudOut1,
Intr => open);
 
end;
/VHDL/t80/T80s.vhd
0,0 → 1,190
--
-- Z80 compatible microprocessor core, synchronous top level
-- Different timing than the original z80
-- Inputs needs to be synchronous and outputs may glitch
--
-- Version : 0242
--
-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org)
--
-- All rights reserved
--
-- Redistribution and use in source and synthezised forms, with or without
-- modification, are permitted provided that the following conditions are met:
--
-- Redistributions of source code must retain the above copyright notice,
-- this list of conditions and the following disclaimer.
--
-- Redistributions in synthesized form must reproduce the above copyright
-- notice, this list of conditions and the following disclaimer in the
-- documentation and/or other materials provided with the distribution.
--
-- Neither the name of the author nor the names of other contributors may
-- be used to endorse or promote products derived from this software without
-- specific prior written permission.
--
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-- POSSIBILITY OF SUCH DAMAGE.
--
-- Please report bugs to the author, but before you do so, please
-- make sure that this is not a derivative work and that
-- you have the latest version of this file.
--
-- The latest version of this file can be found at:
-- http://www.opencores.org/cvsweb.shtml/t80/
--
-- Limitations :
--
-- File history :
--
-- 0208 : First complete release
--
-- 0210 : Fixed read with wait
--
-- 0211 : Fixed interrupt cycle
--
-- 0235 : Updated for T80 interface change
--
-- 0236 : Added T2Write generic
--
-- 0237 : Fixed T2Write with wait state
--
-- 0238 : Updated for T80 interface change
--
-- 0240 : Updated for T80 interface change
--
-- 0242 : Updated for T80 interface change
--
 
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use work.T80_Pack.all;
 
entity T80s is
generic(
Mode : integer := 0; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB
T2Write : integer := 1; -- 0 => WR_n active in T3, /=0 => WR_n active in T2
IOWait : integer := 1 -- 0 => Single cycle I/O, 1 => Std I/O cycle
);
port(
RESET_n : in std_logic;
CLK_n : in std_logic;
WAIT_n : in std_logic;
INT_n : in std_logic;
NMI_n : in std_logic;
BUSRQ_n : in std_logic;
M1_n : out std_logic;
MREQ_n : out std_logic;
IORQ_n : out std_logic;
RD_n : out std_logic;
WR_n : out std_logic;
RFSH_n : out std_logic;
HALT_n : out std_logic;
BUSAK_n : out std_logic;
A : out std_logic_vector(15 downto 0);
DI : in std_logic_vector(7 downto 0);
DO : out std_logic_vector(7 downto 0)
);
end T80s;
 
architecture rtl of T80s is
 
signal CEN : std_logic;
signal IntCycle_n : std_logic;
signal NoRead : std_logic;
signal Write : std_logic;
signal IORQ : std_logic;
signal DI_Reg : std_logic_vector(7 downto 0);
signal MCycle : std_logic_vector(2 downto 0);
signal TState : std_logic_vector(2 downto 0);
 
begin
 
CEN <= '1';
 
u0 : T80
generic map(
Mode => Mode,
IOWait => IOWait)
port map(
CEN => CEN,
M1_n => M1_n,
IORQ => IORQ,
NoRead => NoRead,
Write => Write,
RFSH_n => RFSH_n,
HALT_n => HALT_n,
WAIT_n => Wait_n,
INT_n => INT_n,
NMI_n => NMI_n,
RESET_n => RESET_n,
BUSRQ_n => BUSRQ_n,
BUSAK_n => BUSAK_n,
CLK_n => CLK_n,
A => A,
DInst => DI,
DI => DI_Reg,
DO => DO,
MC => MCycle,
TS => TState,
IntCycle_n => IntCycle_n);
 
process (RESET_n, CLK_n)
begin
if RESET_n = '0' then
RD_n <= '1';
WR_n <= '1';
IORQ_n <= '1';
MREQ_n <= '1';
DI_Reg <= "00000000";
elsif CLK_n'event and CLK_n = '1' then
RD_n <= '1';
WR_n <= '1';
IORQ_n <= '1';
MREQ_n <= '1';
if MCycle = "001" then
if TState = "001" or (TState = "010" and Wait_n = '0') then
RD_n <= not IntCycle_n;
MREQ_n <= not IntCycle_n;
IORQ_n <= IntCycle_n;
end if;
if TState = "011" then
MREQ_n <= '0';
end if;
else
if (TState = "001" or (TState = "010" and Wait_n = '0')) and NoRead = '0' and Write = '0' then
RD_n <= '0';
IORQ_n <= not IORQ;
MREQ_n <= IORQ;
end if;
if T2Write = 0 then
if TState = "010" and Write = '1' then
WR_n <= '0';
IORQ_n <= not IORQ;
MREQ_n <= IORQ;
end if;
else
if (TState = "001" or (TState = "010" and Wait_n = '0')) and Write = '1' then
WR_n <= '0';
IORQ_n <= not IORQ;
MREQ_n <= IORQ;
end if;
end if;
end if;
if TState = "010" and Wait_n = '1' then
DI_Reg <= DI;
end if;
end if;
end process;
 
end;
/VHDL/video_PLL.vhd
0,0 → 1,203
-- megafunction wizard: %ALTPLL%
-- GENERATION: STANDARD
-- VERSION: WM1.0
-- MODULE: altpll
 
-- ============================================================
-- File Name: video_PLL.vhd
-- Megafunction Name(s):
-- altpll
-- ============================================================
-- ************************************************************
-- THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
--
-- 5.0 Build 168 06/22/2005 SP 1 SJ Web Edition
-- ************************************************************
 
 
--Copyright (C) 1991-2005 Altera Corporation
--Your use of Altera Corporation's design tools, logic functions
--and other software and tools, and its AMPP partner logic
--functions, and any output files any of the foregoing
--(including device programming or simulation files), and any
--associated documentation or information are expressly subject
--to the terms and conditions of the Altera Program License
--Subscription Agreement, Altera MegaCore Function License
--Agreement, or other applicable license agreement, including,
--without limitation, that your use is for the sole purpose of
--programming logic devices manufactured by Altera and sold by
--Altera or its authorized distributors. Please refer to the
--applicable agreement for further details.
 
 
LIBRARY ieee;
USE ieee.std_logic_1164.all;
 
LIBRARY altera_mf;
USE altera_mf.altera_mf_components.all;
 
ENTITY video_PLL IS
PORT
(
inclk0 : IN STD_LOGIC := '0';
c0 : OUT STD_LOGIC
);
END video_PLL;
 
 
ARCHITECTURE SYN OF video_pll IS
 
SIGNAL sub_wire0 : STD_LOGIC_VECTOR (5 DOWNTO 0);
SIGNAL sub_wire1 : STD_LOGIC ;
SIGNAL sub_wire2 : STD_LOGIC ;
SIGNAL sub_wire3 : STD_LOGIC_VECTOR (1 DOWNTO 0);
SIGNAL sub_wire4_bv : BIT_VECTOR (0 DOWNTO 0);
SIGNAL sub_wire4 : STD_LOGIC_VECTOR (0 DOWNTO 0);
 
 
 
COMPONENT altpll
GENERIC (
clk0_duty_cycle : NATURAL;
lpm_type : STRING;
clk0_multiply_by : NATURAL;
inclk0_input_frequency : NATURAL;
clk0_divide_by : NATURAL;
pll_type : STRING;
intended_device_family : STRING;
operation_mode : STRING;
compensate_clock : STRING;
clk0_phase_shift : STRING
);
PORT (
inclk : IN STD_LOGIC_VECTOR (1 DOWNTO 0);
clk : OUT STD_LOGIC_VECTOR (5 DOWNTO 0)
);
END COMPONENT;
 
BEGIN
sub_wire4_bv(0 DOWNTO 0) <= "0";
sub_wire4 <= To_stdlogicvector(sub_wire4_bv);
sub_wire1 <= sub_wire0(0);
c0 <= sub_wire1;
sub_wire2 <= inclk0;
sub_wire3 <= sub_wire4(0 DOWNTO 0) & sub_wire2;
 
altpll_component : altpll
GENERIC MAP (
clk0_duty_cycle => 50,
lpm_type => "altpll",
clk0_multiply_by => 1,
inclk0_input_frequency => 20000,
clk0_divide_by => 2,
pll_type => "FAST",
intended_device_family => "Cyclone II",
operation_mode => "NORMAL",
compensate_clock => "CLK0",
clk0_phase_shift => "0"
)
PORT MAP (
inclk => sub_wire3,
clk => sub_wire0
);
 
 
 
END SYN;
 
-- ============================================================
-- CNX file retrieval info
-- ============================================================
-- Retrieval info: PRIVATE: MIRROR_CLK0 STRING "0"
-- Retrieval info: PRIVATE: PHASE_SHIFT_UNIT0 STRING "deg"
-- Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT0 STRING "MHz"
-- Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_COMBO STRING "MHz"
-- Retrieval info: PRIVATE: SPREAD_USE STRING "0"
-- Retrieval info: PRIVATE: SPREAD_FEATURE_ENABLED STRING "0"
-- Retrieval info: PRIVATE: GLOCKED_COUNTER_EDIT_CHANGED STRING "1"
-- Retrieval info: PRIVATE: GLOCK_COUNTER_EDIT NUMERIC "1048575"
-- Retrieval info: PRIVATE: SRC_SYNCH_COMP_RADIO STRING "0"
-- Retrieval info: PRIVATE: DUTY_CYCLE0 STRING "50.00000000"
-- Retrieval info: PRIVATE: PHASE_SHIFT0 STRING "0.00000000"
-- Retrieval info: PRIVATE: MULT_FACTOR0 NUMERIC "1"
-- Retrieval info: PRIVATE: OUTPUT_FREQ_MODE0 STRING "1"
-- Retrieval info: PRIVATE: SPREAD_PERCENT STRING "0.500"
-- Retrieval info: PRIVATE: LOCKED_OUTPUT_CHECK STRING "0"
-- Retrieval info: PRIVATE: PLL_ARESET_CHECK STRING "0"
-- Retrieval info: PRIVATE: STICKY_CLK0 STRING "1"
-- Retrieval info: PRIVATE: BANDWIDTH STRING "1.000"
-- Retrieval info: PRIVATE: BANDWIDTH_USE_CUSTOM STRING "0"
-- Retrieval info: PRIVATE: DEVICE_SPEED_GRADE STRING "6"
-- Retrieval info: PRIVATE: SPREAD_FREQ STRING "50.000"
-- Retrieval info: PRIVATE: BANDWIDTH_FEATURE_ENABLED STRING "0"
-- Retrieval info: PRIVATE: LONG_SCAN_RADIO STRING "1"
-- Retrieval info: PRIVATE: PLL_ENHPLL_CHECK NUMERIC "0"
-- Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE_DIRTY NUMERIC "0"
-- Retrieval info: PRIVATE: USE_CLK0 STRING "1"
-- Retrieval info: PRIVATE: INCLK1_FREQ_EDIT_CHANGED STRING "1"
-- Retrieval info: PRIVATE: SCAN_FEATURE_ENABLED STRING "0"
-- Retrieval info: PRIVATE: ZERO_DELAY_RADIO STRING "0"
-- Retrieval info: PRIVATE: PLL_PFDENA_CHECK STRING "0"
-- Retrieval info: PRIVATE: CREATE_CLKBAD_CHECK STRING "0"
-- Retrieval info: PRIVATE: INCLK1_FREQ_EDIT STRING "100.000"
-- Retrieval info: PRIVATE: CUR_DEDICATED_CLK STRING "c0"
-- Retrieval info: PRIVATE: PLL_FASTPLL_CHECK NUMERIC "0"
-- Retrieval info: PRIVATE: ACTIVECLK_CHECK STRING "0"
-- Retrieval info: PRIVATE: BANDWIDTH_FREQ_UNIT STRING "MHz"
-- Retrieval info: PRIVATE: INCLK0_FREQ_UNIT_COMBO STRING "MHz"
-- Retrieval info: PRIVATE: GLOCKED_MODE_CHECK STRING "0"
-- Retrieval info: PRIVATE: NORMAL_MODE_RADIO STRING "1"
-- Retrieval info: PRIVATE: CUR_FBIN_CLK STRING "e0"
-- Retrieval info: PRIVATE: DIV_FACTOR0 NUMERIC "1"
-- Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_CHANGED STRING "1"
-- Retrieval info: PRIVATE: HAS_MANUAL_SWITCHOVER STRING "1"
-- Retrieval info: PRIVATE: EXT_FEEDBACK_RADIO STRING "0"
-- Retrieval info: PRIVATE: PLL_AUTOPLL_CHECK NUMERIC "1"
-- Retrieval info: PRIVATE: CLKLOSS_CHECK STRING "0"
-- Retrieval info: PRIVATE: BANDWIDTH_USE_AUTO STRING "1"
-- Retrieval info: PRIVATE: SHORT_SCAN_RADIO STRING "0"
-- Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE STRING "500.000"
-- Retrieval info: PRIVATE: CLKSWITCH_CHECK STRING "0"
-- Retrieval info: PRIVATE: SPREAD_FREQ_UNIT STRING "KHz"
-- Retrieval info: PRIVATE: PLL_ENA_CHECK STRING "0"
-- Retrieval info: PRIVATE: INCLK0_FREQ_EDIT STRING "50.000"
-- Retrieval info: PRIVATE: CNX_NO_COMPENSATE_RADIO STRING "0"
-- Retrieval info: PRIVATE: INT_FEEDBACK__MODE_RADIO STRING "1"
-- Retrieval info: PRIVATE: OUTPUT_FREQ0 STRING "25.000"
-- Retrieval info: PRIVATE: PRIMARY_CLK_COMBO STRING "inclk0"
-- Retrieval info: PRIVATE: CREATE_INCLK1_CHECK STRING "0"
-- Retrieval info: PRIVATE: SACN_INPUTS_CHECK STRING "0"
-- Retrieval info: PRIVATE: DEV_FAMILY STRING "Cyclone II"
-- Retrieval info: PRIVATE: SWITCHOVER_COUNT_EDIT NUMERIC "1"
-- Retrieval info: PRIVATE: SWITCHOVER_FEATURE_ENABLED STRING "1"
-- Retrieval info: PRIVATE: BANDWIDTH_PRESET STRING "Low"
-- Retrieval info: PRIVATE: GLOCKED_FEATURE_ENABLED STRING "1"
-- Retrieval info: PRIVATE: USE_CLKENA0 STRING "0"
-- Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT0 STRING "deg"
-- Retrieval info: PRIVATE: CLKBAD_SWITCHOVER_CHECK STRING "0"
-- Retrieval info: PRIVATE: BANDWIDTH_USE_PRESET STRING "0"
-- Retrieval info: PRIVATE: PLL_LVDS_PLL_CHECK NUMERIC "0"
-- Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
-- Retrieval info: CONSTANT: CLK0_DUTY_CYCLE NUMERIC "50"
-- Retrieval info: CONSTANT: LPM_TYPE STRING "altpll"
-- Retrieval info: CONSTANT: CLK0_MULTIPLY_BY NUMERIC "1"
-- Retrieval info: CONSTANT: INCLK0_INPUT_FREQUENCY NUMERIC "20000"
-- Retrieval info: CONSTANT: CLK0_DIVIDE_BY NUMERIC "2"
-- Retrieval info: CONSTANT: PLL_TYPE STRING "FAST"
-- Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone II"
-- Retrieval info: CONSTANT: OPERATION_MODE STRING "NORMAL"
-- Retrieval info: CONSTANT: COMPENSATE_CLOCK STRING "CLK0"
-- Retrieval info: CONSTANT: CLK0_PHASE_SHIFT STRING "0"
-- Retrieval info: USED_PORT: c0 0 0 0 0 OUTPUT VCC "c0"
-- Retrieval info: USED_PORT: @clk 0 0 6 0 OUTPUT VCC "@clk[5..0]"
-- Retrieval info: USED_PORT: inclk0 0 0 0 0 INPUT GND "inclk0"
-- Retrieval info: USED_PORT: @extclk 0 0 4 0 OUTPUT VCC "@extclk[3..0]"
-- Retrieval info: USED_PORT: @inclk 0 0 2 0 INPUT VCC "@inclk[1..0]"
-- Retrieval info: CONNECT: @inclk 0 0 1 0 inclk0 0 0 0 0
-- Retrieval info: CONNECT: c0 0 0 0 0 @clk 0 0 1 0
-- Retrieval info: CONNECT: @inclk 0 0 1 1 GND 0 0 0 0
-- Retrieval info: GEN_FILE: TYPE_NORMAL video_PLL.vhd TRUE FALSE
-- Retrieval info: GEN_FILE: TYPE_NORMAL video_PLL.inc FALSE FALSE
-- Retrieval info: GEN_FILE: TYPE_NORMAL video_PLL.cmp TRUE FALSE
-- Retrieval info: GEN_FILE: TYPE_NORMAL video_PLL.bsf FALSE FALSE
-- Retrieval info: GEN_FILE: TYPE_NORMAL video_PLL_inst.vhd TRUE FALSE

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.