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

Subversion Repositories t65

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 6 to Rev 7
    Reverse comparison

Rev 6 → Rev 7

/trunk/rtl/vhdl/T65_ALU.vhd
0,0 → 1,251
--
-- 6502 compatible microprocessor core
--
-- Version : 0245
--
-- 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/t65/
--
-- Limitations :
--
-- File history :
--
-- 0245 : First version
--
 
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use work.T65_Pack.all;
 
entity T65_ALU is
port(
Mode : in std_logic_vector(1 downto 0); -- "00" => 6502, "01" => 65C02, "10" => 65816
Op : in std_logic_vector(3 downto 0);
BusA : in std_logic_vector(7 downto 0);
BusB : in std_logic_vector(7 downto 0);
P_In : in std_logic_vector(7 downto 0);
P_Out : out std_logic_vector(7 downto 0);
Q : out std_logic_vector(7 downto 0)
);
end T65_ALU;
 
architecture rtl of T65_ALU is
 
-- AddSub variables (temporary signals)
signal ADC_Z : std_logic;
signal ADC_C : std_logic;
signal ADC_V : std_logic;
signal ADC_N : std_logic;
signal ADC_Q : std_logic_vector(7 downto 0);
signal SBC_Z : std_logic;
signal SBC_C : std_logic;
signal SBC_V : std_logic;
signal SBC_N : std_logic;
signal SBC_Q : std_logic_vector(7 downto 0);
 
begin
 
process (P_In, BusA, BusB)
variable AL : unsigned(6 downto 0);
variable AH : unsigned(6 downto 0);
variable C : std_logic;
begin
AL := resize(unsigned(BusA(3 downto 0) & P_In(Flag_C)), 7) + resize(unsigned(BusB(3 downto 0) & "1"), 7);
AH := resize(unsigned(BusA(7 downto 4) & AL(5)), 7) + resize(unsigned(BusB(7 downto 4) & "1"), 7);
 
-- pragma translate_off
if is_x(std_logic_vector(AL)) then AL := "0000000"; end if;
if is_x(std_logic_vector(AH)) then AH := "0000000"; end if;
-- pragma translate_on
 
if AL(4 downto 1) = 0 and AH(4 downto 1) = 0 then
ADC_Z <= '1';
else
ADC_Z <= '0';
end if;
 
if AL(5 downto 1) > 9 and P_In(Flag_D) = '1' then
AL(6 downto 1) := AL(6 downto 1) + 6;
end if;
 
C := AL(6) or AL(5);
AH := resize(unsigned(BusA(7 downto 4) & C), 7) + resize(unsigned(BusB(7 downto 4) & "1"), 7);
 
ADC_N <= AH(4);
ADC_V <= (AH(4) xor BusA(7)) and not (BusA(7) xor BusB(7));
 
-- pragma translate_off
if is_x(std_logic_vector(AH)) then AH := "0000000"; end if;
-- pragma translate_on
 
if AH(5 downto 1) > 9 and P_In(Flag_D) = '1' then
AH(6 downto 1) := AH(6 downto 1) + 6;
end if;
 
ADC_C <= AH(6) or AH(5);
 
ADC_Q <= std_logic_vector(AH(4 downto 1) & AL(4 downto 1));
end process;
 
process (Op, P_In, BusA, BusB)
variable AL : unsigned(6 downto 0);
variable AH : unsigned(5 downto 0);
variable C : std_logic;
begin
C := P_In(Flag_C) or not Op(0);
AL := resize(unsigned(BusA(3 downto 0) & C), 7) - resize(unsigned(BusB(3 downto 0) & "1"), 6);
AH := resize(unsigned(BusA(7 downto 4) & "0"), 6) - resize(unsigned(BusB(7 downto 4) & AL(5)), 6);
 
-- pragma translate_off
if is_x(std_logic_vector(AL)) then AL := "0000000"; end if;
if is_x(std_logic_vector(AH)) then AH := "000000"; end if;
-- pragma translate_on
 
if AL(4 downto 1) = 0 and AH(4 downto 1) = 0 then
SBC_Z <= '1';
else
SBC_Z <= '0';
end if;
 
SBC_C <= not AH(5);
SBC_V <= (AH(4) xor BusA(7)) and (BusA(7) xor BusB(7));
SBC_N <= AH(4);
 
if P_In(Flag_D) = '1' then
if AL(5) = '1' then
AL(5 downto 1) := AL(5 downto 1) - 6;
end if;
AH := resize(unsigned(BusA(7 downto 4) & "0"), 6) - resize(unsigned(BusB(7 downto 4) & AL(6)), 6);
if AH(5) = '1' then
AH(5 downto 1) := AH(5 downto 1) - 6;
end if;
end if;
 
SBC_Q <= std_logic_vector(AH(4 downto 1) & AL(4 downto 1));
end process;
 
process (Op, P_In, BusA, BusB,
ADC_Z, ADC_C, ADC_V, ADC_N, ADC_Q,
SBC_Z, SBC_C, SBC_V, SBC_N, SBC_Q)
variable Q_t : std_logic_vector(7 downto 0);
begin
-- ORA, AND, EOR, ADC, NOP, LD, CMP, SBC
-- ASL, ROL, LSR, ROR, BIT, LD, DEC, INC
P_Out <= P_In;
Q_t := BusA;
case Op(3 downto 0) is
when "0000" =>
-- ORA
Q_t := BusA or BusB;
when "0001" =>
-- AND
Q_t := BusA and BusB;
when "0010" =>
-- EOR
Q_t := BusA xor BusB;
when "0011" =>
-- ADC
P_Out(Flag_V) <= ADC_V;
P_Out(Flag_C) <= ADC_C;
Q_t := ADC_Q;
when "0101" | "1101" =>
-- LDA
when "0110" =>
-- CMP
P_Out(Flag_C) <= SBC_C;
when "0111" =>
-- SBC
P_Out(Flag_V) <= SBC_V;
P_Out(Flag_C) <= SBC_C;
Q_t := SBC_Q;
when "1000" =>
-- ASL
Q_t := BusA(6 downto 0) & "0";
P_Out(Flag_C) <= BusA(7);
when "1001" =>
-- ROL
Q_t := BusA(6 downto 0) & P_In(Flag_C);
P_Out(Flag_C) <= BusA(7);
when "1010" =>
-- LSR
Q_t := "0" & BusA(7 downto 1);
P_Out(Flag_C) <= BusA(0);
when "1011" =>
-- ROR
Q_t := P_In(Flag_C) & BusA(7 downto 1);
P_Out(Flag_C) <= BusA(0);
when "1100" =>
-- BIT
P_Out(Flag_V) <= BusB(6);
when "1110" =>
-- DEC
Q_t := std_logic_vector(unsigned(BusA) - 1);
when "1111" =>
-- INC
Q_t := std_logic_vector(unsigned(BusA) + 1);
when others =>
end case;
 
case Op(3 downto 0) is
when "0011" =>
P_Out(Flag_N) <= ADC_N;
P_Out(Flag_Z) <= ADC_Z;
when "0110" | "0111" =>
P_Out(Flag_N) <= SBC_N;
P_Out(Flag_Z) <= SBC_Z;
when "0100" =>
when "1100" =>
P_Out(Flag_N) <= BusB(7);
if (BusA and BusB) = "00000000" then
P_Out(Flag_Z) <= '1';
else
P_Out(Flag_Z) <= '0';
end if;
when others =>
P_Out(Flag_N) <= Q_t(7);
if Q_t = "00000000" then
P_Out(Flag_Z) <= '1';
else
P_Out(Flag_Z) <= '0';
end if;
end case;
 
Q <= Q_t;
end process;
 
end;
/trunk/rtl/vhdl/DebugSystemXR.vhd
0,0 → 1,174
-- 6502, 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 Res_n_s : std_logic;
signal Rd_n : std_logic;
signal Wr_n : std_logic;
signal R_W_n : std_logic;
signal A_i : std_logic_vector(23 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 Rdy : 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
 
Rd_n <= not R_W_n or not Rdy;
Wr_n <= R_W_n or not Rdy;
OE_n <= not R_W_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 R_W_n = '0' else "ZZZZZZZZ";
 
process (Reset_n, Clk)
begin
if Reset_n = '0' then
Res_n_s <= '0';
Rdy <= '0';
elsif Clk'event and Clk = '1' then
Res_n_s <= '1';
Rdy <= not Rdy;
end if;
end process;
 
RAMCS_n_i <= A_i(15);
UART0CS_n <= '0' when A_i(15 downto 3) = "1000000000000" else '1';
UART1CS_n <= '0' when A_i(15 downto 3) = "1000000010000" 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.T65
port map(
Mode => "00",
Res_n => Res_n_s,
Clk => Clk,
Rdy => Rdy,
Abort_n => '1',
IRQ_n => '1',
NMI_n => NMI_n,
SO_n => '1',
R_W_n => R_W_n,
Sync => open,
EF => open,
MF => open,
XF => open,
ML_n => open,
VP_n => open,
VDA => open,
VPA => open,
A => A_i,
DI => CPU_D,
DO => D_i);
 
u1 : entity work.Mon65XR
port map(
Clk => Clk,
A => A_i(9 downto 0),
D => ROM_D);
 
u3 : entity work.T16450
port map(
MR_n => Res_n_s,
XIn => Clk,
RClk => BaudOut0,
CS_n => UART0CS_n,
Rd_n => Rd_n,
Wr_n => Wr_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 => Res_n_s,
XIn => Clk,
RClk => BaudOut1,
CS_n => UART1CS_n,
Rd_n => Rd_n,
Wr_n => Wr_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;
/trunk/rtl/vhdl/T65_MCode.vhd
0,0 → 1,941
--
-- 65xx compatible microprocessor core
--
-- Version : 0246
--
-- 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/t65/
--
-- Limitations :
--
-- 65C02
-- supported : inc, dec, phx, plx, phy, ply
-- missing : bra, ora, lda, cmp, sbc, tsb*2, trb*2, stz*2, bit*2, wai, stp, jmp, bbr*8, bbs*8
--
-- File history :
--
-- 0246 : First release
--
 
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use work.T65_Pack.all;
 
entity T65_MCode is
port(
Mode : in std_logic_vector(1 downto 0); -- "00" => 6502, "01" => 65C02, "10" => 65816
IR : in std_logic_vector(7 downto 0);
MCycle : in std_logic_vector(2 downto 0);
P : in std_logic_vector(7 downto 0);
LCycle : out std_logic_vector(2 downto 0);
ALU_Op : out std_logic_vector(3 downto 0);
Set_BusA_To : out std_logic_vector(2 downto 0); -- DI,A,X,Y,S,P
Set_Addr_To : out std_logic_vector(1 downto 0); -- PC Adder,S,AD,BA
Write_Data : out std_logic_vector(2 downto 0); -- DL,A,X,Y,S,P,PCL,PCH
Jump : out std_logic_vector(1 downto 0); -- PC,++,DIDL,Rel
BAAdd : out std_logic_vector(1 downto 0); -- None,DB Inc,BA Add,BA Adj
BreakAtNA : out std_logic;
ADAdd : out std_logic;
PCAdd : out std_logic;
Inc_S : out std_logic;
Dec_S : out std_logic;
LDA : out std_logic;
LDP : out std_logic;
LDX : out std_logic;
LDY : out std_logic;
LDS : out std_logic;
LDDI : out std_logic;
LDALU : out std_logic;
LDAD : out std_logic;
LDBAL : out std_logic;
LDBAH : out std_logic;
SaveP : out std_logic;
Write : out std_logic
);
end T65_MCode;
 
architecture rtl of T65_MCode is
 
signal Branch : std_logic;
 
begin
 
with IR(7 downto 5) select
Branch <= not P(Flag_N) when "000",
P(Flag_N) when "001",
not P(Flag_V) when "010",
P(Flag_V) when "011",
not P(Flag_C) when "100",
P(Flag_C) when "101",
not P(Flag_Z) when "110",
P(Flag_Z) when others;
 
process (IR, MCycle, P, Branch, Mode)
begin
LCycle <= "001";
Set_BusA_To <= "001"; -- A
Set_Addr_To <= (others => '0');
Write_Data <= (others => '0');
Jump <= (others => '0');
BAAdd <= "00";
BreakAtNA <= '0';
ADAdd <= '0';
PCAdd <= '0';
Inc_S <= '0';
Dec_S <= '0';
LDA <= '0';
LDP <= '0';
LDX <= '0';
LDY <= '0';
LDS <= '0';
LDDI <= '0';
LDALU <= '0';
LDAD <= '0';
LDBAL <= '0';
LDBAH <= '0';
SaveP <= '0';
Write <= '0';
 
case IR(7 downto 5) is
when "100" =>
case IR(1 downto 0) is
when "00" =>
Set_BusA_To <= "011"; -- Y
Write_Data <= "011"; -- Y
when "10" =>
Set_BusA_To <= "010"; -- X
Write_Data <= "010"; -- X
when others =>
Write_Data <= "001"; -- A
end case;
when "101" =>
case IR(1 downto 0) is
when "00" =>
if IR(4) /= '1' or IR(2) /= '0' then
LDY <= '1';
end if;
when "10" =>
LDX <= '1';
when others =>
LDA <= '1';
end case;
Set_BusA_To <= "000"; -- DI
when "110" =>
case IR(1 downto 0) is
when "00" =>
if IR(4) = '0' then
LDY <= '1';
end if;
Set_BusA_To <= "011"; -- Y
when others =>
Set_BusA_To <= "001"; -- A
end case;
when "111" =>
case IR(1 downto 0) is
when "00" =>
if IR(4) = '0' then
LDX <= '1';
end if;
Set_BusA_To <= "010"; -- X
when others =>
Set_BusA_To <= "001"; -- A
end case;
when others =>
end case;
 
if IR(7 downto 6) /= "10" and IR(1 downto 0) = "10" then
Set_BusA_To <= "000"; -- DI
end if;
 
case IR(4 downto 0) is
when "00000" | "01000" | "01010" | "11000" | "11010" =>
-- Implied
case IR is
when "00000000" =>
-- BRK
LCycle <= "110";
case to_integer(unsigned(MCycle)) is
when 1 =>
Set_Addr_To <= "01"; -- S
Write_Data <= "111"; -- PCH
Write <= '1';
when 2 =>
Dec_S <= '1';
Set_Addr_To <= "01"; -- S
Write_Data <= "110"; -- PCL
Write <= '1';
when 3 =>
Dec_S <= '1';
Set_Addr_To <= "01"; -- S
Write_Data <= "101"; -- P
Write <= '1';
when 4 =>
Dec_S <= '1';
Set_Addr_To <= "11"; -- BA
when 5 =>
LDDI <= '1';
Set_Addr_To <= "11"; -- BA
when 6 =>
Jump <= "10"; -- DIDL
when others =>
end case;
when "00100000" =>
-- JSR
LCycle <= "101";
case to_integer(unsigned(MCycle)) is
when 1 =>
Jump <= "01";
LDDI <= '1';
Set_Addr_To <= "01"; -- S
when 2 =>
Set_Addr_To <= "01"; -- S
Write_Data <= "111"; -- PCH
Write <= '1';
when 3 =>
Dec_S <= '1';
Set_Addr_To <= "01"; -- S
Write_Data <= "110"; -- PCL
Write <= '1';
when 4 =>
Dec_S <= '1';
when 5 =>
Jump <= "10"; -- DIDL
when others =>
end case;
when "01000000" =>
-- RTI
LCycle <= "101";
case to_integer(unsigned(MCycle)) is
when 1 =>
Set_Addr_To <= "01"; -- S
when 2 =>
Inc_S <= '1';
Set_Addr_To <= "01"; -- S
when 3 =>
Inc_S <= '1';
Set_Addr_To <= "01"; -- S
Set_BusA_To <= "000"; -- DI
when 4 =>
LDP <= '1';
Inc_S <= '1';
LDDI <= '1';
Set_Addr_To <= "01"; -- S
when 5 =>
Jump <= "10"; -- DIDL
when others =>
end case;
when "01100000" =>
-- RTS
LCycle <= "101";
case to_integer(unsigned(MCycle)) is
when 1 =>
Set_Addr_To <= "01"; -- S
when 2 =>
Inc_S <= '1';
Set_Addr_To <= "01"; -- S
when 3 =>
Inc_S <= '1';
LDDI <= '1';
Set_Addr_To <= "01"; -- S
when 4 =>
Jump <= "10"; -- DIDL
when 5 =>
Jump <= "01";
when others =>
end case;
when "00001000" | "01001000" | "01011010" | "11011010" =>
-- PHP, PHA, PHY*, PHX*
LCycle <= "010";
if Mode = "00" and IR(1) = '1' then
LCycle <= "001";
end if;
case to_integer(unsigned(MCycle)) is
when 1 =>
case IR(7 downto 4) is
when "0000" =>
Write_Data <= "101"; -- P
when "0100" =>
Write_Data <= "001"; -- A
when "0101" =>
Write_Data <= "011"; -- Y
when "1101" =>
Write_Data <= "010"; -- X
when others =>
end case;
Write <= '1';
Set_Addr_To <= "01"; -- S
when 2 =>
Dec_S <= '1';
when others =>
end case;
when "00101000" | "01101000" | "01111010" | "11111010" =>
-- PLP, PLA, PLY*, PLX*
LCycle <= "011";
if Mode = "00" and IR(1) = '1' then
LCycle <= "001";
end if;
case IR(7 downto 4) is
when "0010" =>
LDP <= '1';
when "0110" =>
LDA <= '1';
when "0111" =>
if Mode /= "00" then
LDY <= '1';
end if;
when "1111" =>
if Mode /= "00" then
LDX <= '1';
end if;
when others =>
end case;
case to_integer(unsigned(MCycle)) is
when 0 =>
SaveP <= '1';
when 1 =>
Set_Addr_To <= "01"; -- S
when 2 =>
Inc_S <= '1';
Set_Addr_To <= "01"; -- S
when 3 =>
Set_BusA_To <= "000"; -- DI
when others =>
end case;
when "10100000" | "11000000" | "11100000" =>
-- LDY, CPY, CPX
-- Immediate
case to_integer(unsigned(MCycle)) is
when 0 =>
when 1 =>
Jump <= "01";
when others =>
end case;
when "10001000" =>
-- DEY
LDY <= '1';
case to_integer(unsigned(MCycle)) is
when 0 =>
when 1 =>
Set_BusA_To <= "011"; -- Y
when others =>
end case;
when "11001010" =>
-- DEX
LDX <= '1';
case to_integer(unsigned(MCycle)) is
when 0 =>
when 1 =>
Set_BusA_To <= "010"; -- X
when others =>
end case;
when "00011010" | "00111010" =>
-- INC*, DEC*
if Mode /= "00" then
LDA <= '1'; -- A
end if;
case to_integer(unsigned(MCycle)) is
when 0 =>
when 1 =>
Set_BusA_To <= "100"; -- S
when others =>
end case;
when "00001010" | "00101010" | "01001010" | "01101010" =>
-- ASL, ROL, LSR, ROR
LDA <= '1'; -- A
Set_BusA_To <= "001"; -- A
case to_integer(unsigned(MCycle)) is
when 0 =>
when 1 =>
when others =>
end case;
when "10001010" | "10011000" =>
-- TYA, TXA
LDA <= '1'; -- A
case to_integer(unsigned(MCycle)) is
when 0 =>
when 1 =>
when others =>
end case;
when "10101010" | "10101000" =>
-- TAX, TAY
case to_integer(unsigned(MCycle)) is
when 0 =>
when 1 =>
Set_BusA_To <= "001"; -- A
when others =>
end case;
when "10011010" =>
-- TXS
case to_integer(unsigned(MCycle)) is
when 0 =>
LDS <= '1';
when 1 =>
when others =>
end case;
when "10111010" =>
-- TSX
LDX <= '1';
case to_integer(unsigned(MCycle)) is
when 0 =>
when 1 =>
Set_BusA_To <= "100"; -- S
when others =>
end case;
 
-- when "00011000" | "00111000" | "01011000" | "01111000" | "10111000" | "11011000" | "11111000" | "11001000" | "11101000" =>
-- -- CLC, SEC, CLI, SEI, CLV, CLD, SED, INY, INX
-- case to_integer(unsigned(MCycle)) is
-- when 1 =>
-- when others =>
-- end case;
when others =>
case to_integer(unsigned(MCycle)) is
when 0 =>
when others =>
end case;
end case;
 
when "00001" | "00011" =>
-- Zero Page Indexed Indirect (d,x)
LCycle <= "101";
if IR(7 downto 6) /= "10" then
LDA <= '1';
end if;
case to_integer(unsigned(MCycle)) is
when 0 =>
when 1 =>
Jump <= "01";
LDAD <= '1';
Set_Addr_To <= "10"; -- AD
when 2 =>
ADAdd <= '1';
Set_Addr_To <= "10"; -- AD
when 3 =>
BAAdd <= "01"; -- DB Inc
LDBAL <= '1';
Set_Addr_To <= "10"; -- AD
when 4 =>
LDBAH <= '1';
if IR(7 downto 5) = "100" then
Write <= '1';
end if;
Set_Addr_To <= "11"; -- BA
when 5 =>
when others =>
end case;
 
when "01001" | "01011" =>
-- Immediate
LDA <= '1';
case to_integer(unsigned(MCycle)) is
when 0 =>
when 1 =>
Jump <= "01";
when others =>
end case;
 
when "00010" | "10010" =>
-- Immediate, KIL
LDX <= '1';
case to_integer(unsigned(MCycle)) is
when 0 =>
when 1 =>
if IR = "10100010" then
-- LDX
Jump <= "01";
else
-- KIL !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
end if;
when others =>
end case;
 
when "00100" =>
-- Zero Page
LCycle <= "010";
case to_integer(unsigned(MCycle)) is
when 0 =>
if IR(7 downto 5) = "001" then
SaveP <= '1';
end if;
when 1 =>
Jump <= "01";
LDAD <= '1';
if IR(7 downto 5) = "100" then
Write <= '1';
end if;
Set_Addr_To <= "10"; -- AD
when 2 =>
when others =>
end case;
 
when "00101" | "00110" | "00111" =>
-- Zero Page
if IR(7 downto 6) /= "10" and IR(1 downto 0) = "10" then
-- Read-Modify-Write
LCycle <= "100";
case to_integer(unsigned(MCycle)) is
when 1 =>
Jump <= "01";
LDAD <= '1';
Set_Addr_To <= "10"; -- AD
when 2 =>
LDDI <= '1';
Write <= '1';
Set_Addr_To <= "10"; -- AD
when 3 =>
LDALU <= '1';
SaveP <= '1';
Write <= '1';
Set_Addr_To <= "10"; -- AD
when 4 =>
when others =>
end case;
else
LCycle <= "010";
if IR(7 downto 6) /= "10" then
LDA <= '1';
end if;
case to_integer(unsigned(MCycle)) is
when 0 =>
when 1 =>
Jump <= "01";
LDAD <= '1';
if IR(7 downto 5) = "100" then
Write <= '1';
end if;
Set_Addr_To <= "10"; -- AD
when 2 =>
when others =>
end case;
end if;
 
when "01100" =>
-- Absolute
if IR(7 downto 6) = "01" and IR(4 downto 0) = "01100" then
-- JMP
if IR(5) = '0' then
LCycle <= "011";
case to_integer(unsigned(MCycle)) is
when 2 =>
Jump <= "01";
LDDI <= '1';
when 3 =>
Jump <= "10"; -- DIDL
when others =>
end case;
else
LCycle <= "101";
case to_integer(unsigned(MCycle)) is
when 2 =>
Jump <= "01";
LDDI <= '1';
LDBAL <= '1';
when 3 =>
LDBAH <= '1';
if Mode /= "00" then
Jump <= "10"; -- DIDL
end if;
if Mode = "00" then
Set_Addr_To <= "11"; -- BA
end if;
when 4 =>
LDDI <= '1';
if Mode = "00" then
Set_Addr_To <= "11"; -- BA
BAAdd <= "01"; -- DB Inc
else
Jump <= "01";
end if;
when 5 =>
Jump <= "10"; -- DIDL
when others =>
end case;
end if;
else
LCycle <= "011";
case to_integer(unsigned(MCycle)) is
when 0 =>
if IR(7 downto 5) = "001" then
SaveP <= '1';
end if;
when 1 =>
Jump <= "01";
LDBAL <= '1';
when 2 =>
Jump <= "01";
LDBAH <= '1';
if IR(7 downto 5) = "100" then
Write <= '1';
end if;
Set_Addr_To <= "11"; -- BA
when 3 =>
when others =>
end case;
end if;
 
when "01101" | "01110" | "01111" =>
-- Absolute
if IR(7 downto 6) /= "10" and IR(1 downto 0) = "10" then
-- Read-Modify-Write
LCycle <= "101";
case to_integer(unsigned(MCycle)) is
when 1 =>
Jump <= "01";
LDBAL <= '1';
when 2 =>
Jump <= "01";
LDBAH <= '1';
Set_Addr_To <= "11"; -- BA
when 3 =>
LDDI <= '1';
Write <= '1';
Set_Addr_To <= "11"; -- BA
when 4 =>
Write <= '1';
LDALU <= '1';
SaveP <= '1';
Set_Addr_To <= "11"; -- BA
when 5 =>
SaveP <= '1';
when others =>
end case;
else
LCycle <= "011";
if IR(7 downto 6) /= "10" then
LDA <= '1';
end if;
case to_integer(unsigned(MCycle)) is
when 0 =>
when 1 =>
Jump <= "01";
LDBAL <= '1';
when 2 =>
Jump <= "01";
LDBAH <= '1';
if IR(7 downto 5) = "100" then
Write <= '1';
end if;
Set_Addr_To <= "11"; -- BA
when 3 =>
when others =>
end case;
end if;
 
when "10000" =>
-- Relative
if Branch = '1' then
LCycle <= "100";
else
LCycle <= "010";
end if;
case to_integer(unsigned(MCycle)) is
when 2 =>
Jump <= "01";
LDDI <= '1';
when 3 =>
Jump <= "11"; -- Rel
PCAdd <= '1';
when 4 =>
when others =>
end case;
 
when "10001" | "10011" =>
-- Zero Page Indirect Indexed (d),y
LCycle <= "101";
if IR(7 downto 6) /= "10" then
LDA <= '1';
end if;
case to_integer(unsigned(MCycle)) is
when 0 =>
when 1 =>
Jump <= "01";
LDAD <= '1';
Set_Addr_To <= "10"; -- AD
when 2 =>
LDBAL <= '1';
BAAdd <= "01"; -- DB Inc
Set_Addr_To <= "10"; -- AD
when 3 =>
Set_BusA_To <= "011"; -- Y
BAAdd <= "10"; -- BA Add
LDBAH <= '1';
Set_Addr_To <= "11"; -- BA
when 4 =>
BAAdd <= "11"; -- BA Adj
if IR(7 downto 5) = "100" then
Write <= '1';
else
BreakAtNA <= '1';
end if;
Set_Addr_To <= "11"; -- BA
when 5 =>
when others =>
end case;
 
when "10100" | "10101" | "10110" | "10111" =>
-- Zero Page, X
if IR(7 downto 6) /= "10" and IR(1 downto 0) = "10" then
-- Read-Modify-Write
LCycle <= "101";
case to_integer(unsigned(MCycle)) is
when 1 =>
Jump <= "01";
LDAD <= '1';
Set_Addr_To <= "10"; -- AD
when 2 =>
ADAdd <= '1';
Set_Addr_To <= "10"; -- AD
when 3 =>
LDDI <= '1';
Write <= '1';
Set_Addr_To <= "10"; -- AD
when 4 =>
LDALU <= '1';
SaveP <= '1';
Write <= '1';
Set_Addr_To <= "10"; -- AD
when 5 =>
when others =>
end case;
else
LCycle <= "011";
if IR(7 downto 6) /= "10" then
LDA <= '1';
end if;
case to_integer(unsigned(MCycle)) is
when 0 =>
when 1 =>
Jump <= "01";
LDAD <= '1';
Set_Addr_To <= "10"; -- AD
when 2 =>
ADAdd <= '1';
if IR(7 downto 5) = "100" then
Write <= '1';
end if;
Set_Addr_To <= "10"; -- AD
when 3 =>
when others =>
end case;
end if;
 
when "11001" | "11011" =>
-- Absolute Y
LCycle <= "100";
if IR(7 downto 6) /= "10" then
LDA <= '1';
end if;
case to_integer(unsigned(MCycle)) is
when 0 =>
when 1 =>
Jump <= "01";
LDBAL <= '1';
when 2 =>
Jump <= "01";
Set_BusA_To <= "011"; -- Y
BAAdd <= "10"; -- BA Add
LDBAH <= '1';
Set_Addr_To <= "11"; -- BA
when 3 =>
BAAdd <= "11"; -- BA adj
if IR(7 downto 5) = "100" then
Write <= '1';
else
BreakAtNA <= '1';
end if;
Set_Addr_To <= "11"; -- BA
when 4 =>
when others =>
end case;
 
when "11100" | "11101" | "11110" | "11111" =>
-- Absolute X
if IR(7 downto 6) /= "10" and IR(1 downto 0) = "10" then
-- Read-Modify-Write
LCycle <= "110";
case to_integer(unsigned(MCycle)) is
when 1 =>
Jump <= "01";
LDBAL <= '1';
when 2 =>
Jump <= "01";
Set_BusA_To <= "010"; -- X
BAAdd <= "10"; -- BA Add
LDBAH <= '1';
Set_Addr_To <= "11"; -- BA
when 3 =>
BAAdd <= "11"; -- BA adj
Set_Addr_To <= "11"; -- BA
when 4 =>
LDDI <= '1';
Write <= '1';
Set_Addr_To <= "11"; -- BA
when 5 =>
LDALU <= '1';
SaveP <= '1';
Write <= '1';
Set_Addr_To <= "11"; -- BA
when 6 =>
when others =>
end case;
else
LCycle <= "100";
if IR(7 downto 6) /= "10" then
LDA <= '1';
end if;
case to_integer(unsigned(MCycle)) is
when 0 =>
when 1 =>
Jump <= "01";
LDBAL <= '1';
when 2 =>
Jump <= "01";
Set_BusA_To <= "010"; -- X
BAAdd <= "10"; -- BA Add
LDBAH <= '1';
Set_Addr_To <= "11"; -- BA
when 3 =>
BAAdd <= "11"; -- BA adj
if IR(7 downto 5) = "100" then
Write <= '1';
else
BreakAtNA <= '1';
end if;
Set_Addr_To <= "11"; -- BA
when 4 =>
when others =>
end case;
end if;
when others =>
end case;
end process;
 
process (IR, MCycle)
begin
-- ORA, AND, EOR, ADC, NOP, LD, CMP, SBC
-- ASL, ROL, LSR, ROR, BIT, LD, DEC, INC
case IR(1 downto 0) is
when "00" =>
case IR(4 downto 2) is
when "000" | "001" | "011" =>
case IR(7 downto 5) is
when "110" | "111" =>
-- CP
ALU_Op <= "0110";
when "101" =>
-- LD
ALU_Op <= "0101";
when "001" =>
-- BIT
ALU_Op <= "1100";
when others =>
-- NOP/ST
ALU_Op <= "0100";
end case;
when "010" =>
case IR(7 downto 5) is
when "111" | "110" =>
-- IN
ALU_Op <= "1111";
when "100" =>
-- DEY
ALU_Op <= "1110";
when others =>
-- LD
ALU_Op <= "1101";
end case;
when "110" =>
case IR(7 downto 5) is
when "100" =>
-- TYA
ALU_Op <= "1101";
when others =>
ALU_Op <= "----";
end case;
when others =>
case IR(7 downto 5) is
when "101" =>
-- LD
ALU_Op <= "1101";
when others =>
ALU_Op <= "0100";
end case;
end case;
when "01" =>
ALU_Op(3) <= '0';
ALU_Op(2 downto 0) <= IR(7 downto 5);
when "10" =>
ALU_Op(3) <= '1';
ALU_Op(2 downto 0) <= IR(7 downto 5);
case IR(7 downto 5) is
when "000" =>
if IR(4 downto 2) = "110" then
-- INC
ALU_Op <= "1111";
end if;
when "001" =>
if IR(4 downto 2) = "110" then
-- DEC
ALU_Op <= "1110";
end if;
when "100" =>
if IR(4 downto 2) = "010" then
-- TXA
ALU_Op <= "0101";
else
ALU_Op <= "0100";
end if;
when others =>
end case;
when others =>
case IR(7 downto 5) is
when "100" =>
ALU_Op <= "0100";
when others =>
if MCycle = "000" then
ALU_Op(3) <= '0';
ALU_Op(2 downto 0) <= IR(7 downto 5);
else
ALU_Op(3) <= '1';
ALU_Op(2 downto 0) <= IR(7 downto 5);
end if;
end case;
end case;
end process;
 
end;
/trunk/rtl/vhdl/T65_Pack.vhd
0,0 → 1,132
--
-- 65xx compatible microprocessor core
--
-- Version : 0246
--
-- 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/t65/
--
-- Limitations :
--
-- File history :
--
 
library IEEE;
use IEEE.std_logic_1164.all;
 
package T65_Pack is
 
constant Flag_C : integer := 0;
constant Flag_Z : integer := 1;
constant Flag_I : integer := 2;
constant Flag_D : integer := 3;
constant Flag_B : integer := 4;
constant Flag_1 : integer := 5;
constant Flag_V : integer := 6;
constant Flag_N : integer := 7;
 
component T65
port(
Mode : in std_logic_vector(1 downto 0); -- "00" => 6502, "01" => 65C02, "10" => 65816
Res_n : in std_logic;
Clk : in std_logic;
Rdy : in std_logic;
Abort_n : in std_logic;
IRQ_n : in std_logic;
NMI_n : in std_logic;
SO_n : in std_logic;
R_W_n : out std_logic;
Sync : out std_logic;
EF : out std_logic;
MF : out std_logic;
XF : out std_logic;
ML_n : out std_logic;
VP_n : out std_logic;
VDA : out std_logic;
VPA : out std_logic;
A : out std_logic_vector(23 downto 0);
DI : in std_logic_vector(7 downto 0);
DO : out std_logic_vector(7 downto 0)
);
end component;
 
component T65_MCode
port(
Mode : in std_logic_vector(1 downto 0); -- "00" => 6502, "01" => 65C02, "10" => 65816
IR : in std_logic_vector(7 downto 0);
MCycle : in std_logic_vector(2 downto 0);
P : in std_logic_vector(7 downto 0);
LCycle : out std_logic_vector(2 downto 0);
ALU_Op : out std_logic_vector(3 downto 0);
Set_BusA_To : out std_logic_vector(2 downto 0); -- DI,A,X,Y,S,P
Set_Addr_To : out std_logic_vector(1 downto 0); -- PC Adder,S,AD,BA
Write_Data : out std_logic_vector(2 downto 0); -- DL,A,X,Y,S,P,PCL,PCH
Jump : out std_logic_vector(1 downto 0); -- PC,++,DIDL,Rel
BAAdd : out std_logic_vector(1 downto 0); -- None,DB Inc,BA Add,BA Adj
BreakAtNA : out std_logic;
ADAdd : out std_logic;
PCAdd : out std_logic;
Inc_S : out std_logic;
Dec_S : out std_logic;
LDA : out std_logic;
LDP : out std_logic;
LDX : out std_logic;
LDY : out std_logic;
LDS : out std_logic;
LDDI : out std_logic;
LDALU : out std_logic;
LDAD : out std_logic;
LDBAL : out std_logic;
LDBAH : out std_logic;
SaveP : out std_logic;
Write : out std_logic
);
end component;
 
component T65_ALU
port(
Mode : in std_logic_vector(1 downto 0); -- "00" => 6502, "01" => 65C02, "10" => 65C816
Op : in std_logic_vector(3 downto 0);
BusA : in std_logic_vector(7 downto 0);
BusB : in std_logic_vector(7 downto 0);
P_In : in std_logic_vector(7 downto 0);
P_Out : out std_logic_vector(7 downto 0);
Q : out std_logic_vector(7 downto 0)
);
end component;
 
end;
/trunk/rtl/vhdl/T65.vhd
0,0 → 1,507
--
-- 65xx compatible microprocessor core
--
-- Version : 0246
--
-- 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/t65/
--
-- Limitations :
--
-- 65C02 and 65C816 modes are incomplete
-- Undocumented instructions are not supported
-- Some interface signals behaves incorrect
--
-- File history :
--
-- 0246 : First release
--
 
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use work.T65_Pack.all;
 
entity T65 is
port(
Mode : in std_logic_vector(1 downto 0); -- "00" => 6502, "01" => 65C02, "10" => 65C816
Res_n : in std_logic;
Clk : in std_logic;
Rdy : in std_logic;
Abort_n : in std_logic;
IRQ_n : in std_logic;
NMI_n : in std_logic;
SO_n : in std_logic;
R_W_n : out std_logic;
Sync : out std_logic;
EF : out std_logic;
MF : out std_logic;
XF : out std_logic;
ML_n : out std_logic;
VP_n : out std_logic;
VDA : out std_logic;
VPA : out std_logic;
A : out std_logic_vector(23 downto 0);
DI : in std_logic_vector(7 downto 0);
DO : out std_logic_vector(7 downto 0)
);
end T65;
 
architecture rtl of T65 is
 
-- Registers
signal ABC, X, Y, D : std_logic_vector(15 downto 0);
signal P, AD, DL : std_logic_vector(7 downto 0);
signal BAH : std_logic_vector(7 downto 0);
signal BAL : std_logic_vector(8 downto 0);
signal PBR : std_logic_vector(7 downto 0);
signal DBR : std_logic_vector(7 downto 0);
signal PC : unsigned(15 downto 0);
signal S : unsigned(15 downto 0);
signal EF_i : std_logic;
signal MF_i : std_logic;
signal XF_i : std_logic;
 
signal IR : std_logic_vector(7 downto 0);
 
signal MCycle : std_logic_vector(2 downto 0);
 
signal Mode_r : std_logic_vector(1 downto 0);
signal ALU_Op_r : std_logic_vector(3 downto 0);
signal Write_Data_r : std_logic_vector(2 downto 0);
signal Set_Addr_To_r : std_logic_vector(1 downto 0);
 
signal PCAdder : unsigned(8 downto 0);
 
signal RstCycle : std_logic;
signal IRQCycle : std_logic;
signal NMICycle : std_logic;
 
signal B_o : std_logic;
signal SO_n_o : std_logic;
signal IRQ_n_o : std_logic;
signal NMI_n_o : std_logic;
signal NMIAct : std_logic;
 
signal Break : std_logic;
 
-- ALU signals
signal BusA : std_logic_vector(7 downto 0);
signal BusA_r : std_logic_vector(7 downto 0);
signal BusB : std_logic_vector(7 downto 0);
signal ALU_Q : std_logic_vector(7 downto 0);
signal P_Out : std_logic_vector(7 downto 0);
 
-- Micro code outputs
signal LCycle : std_logic_vector(2 downto 0);
signal ALU_Op : std_logic_vector(3 downto 0);
signal Set_BusA_To : std_logic_vector(2 downto 0);
signal Set_Addr_To : std_logic_vector(1 downto 0);
signal Write_Data : std_logic_vector(2 downto 0);
signal Jump : std_logic_vector(1 downto 0);
signal BAAdd : std_logic_vector(1 downto 0);
signal BreakAtNA : std_logic;
signal ADAdd : std_logic;
signal PCAdd : std_logic;
signal Inc_S : std_logic;
signal Dec_S : std_logic;
signal LDA : std_logic;
signal LDP : std_logic;
signal LDX : std_logic;
signal LDY : std_logic;
signal LDS : std_logic;
signal LDDI : std_logic;
signal LDALU : std_logic;
signal LDAD : std_logic;
signal LDBAL : std_logic;
signal LDBAH : std_logic;
signal SaveP : std_logic;
signal Write : std_logic;
 
begin
 
Sync <= '1' when MCycle = "000" else '0';
EF <= EF_i;
MF <= MF_i;
XF <= XF_i;
ML_n <= '0' when IR(7 downto 6) /= "10" and IR(2 downto 1) = "11" and MCycle(2 downto 1) /= "00" else '1';
VP_n <= '0' when IRQCycle = '1' and (MCycle = "101" or MCycle = "110") else '1';
VDA <= '1' when Set_Addr_To_r /= "000" else '0'; -- Incorrect !!!!!!!!!!!!
VPA <= '1' when Jump(1) = '0' else '0'; -- Incorrect !!!!!!!!!!!!
 
mcode : T65_MCode
port map(
Mode => Mode_r,
IR => IR,
MCycle => MCycle,
P => P,
LCycle => LCycle,
ALU_Op => ALU_Op,
Set_BusA_To => Set_BusA_To,
Set_Addr_To => Set_Addr_To,
Write_Data => Write_Data,
Jump => Jump,
BAAdd => BAAdd,
BreakAtNA => BreakAtNA,
ADAdd => ADAdd,
PCAdd => PCAdd,
Inc_S => Inc_S,
Dec_S => Dec_S,
LDA => LDA,
LDP => LDP,
LDX => LDX,
LDY => LDY,
LDS => LDS,
LDDI => LDDI,
LDALU => LDALU,
LDAD => LDAD,
LDBAL => LDBAL,
LDBAH => LDBAH,
SaveP => SaveP,
Write => Write);
 
alu : T65_ALU
port map(
Mode => Mode_r,
Op => ALU_Op_r,
BusA => BusA_r,
BusB => BusB,
P_In => P,
P_Out => P_Out,
Q => ALU_Q);
 
process (Res_n, Clk)
begin
if Res_n = '0' then
PC <= (others => '0'); -- Program Counter
IR <= "00000000";
 
S <= (others => '0'); -- Dummy !!!!!!!!!!!!!!!!!!!!!
 
D <= (others => '0');
PBR <= (others => '0');
DBR <= (others => '0');
 
Mode_r <= (others => '0');
ALU_Op_r <= "1100";
Write_Data_r <= "000";
Set_Addr_To_r <= "00";
 
R_W_n <= '1';
EF_i <= '1';
MF_i <= '1';
XF_i <= '1';
 
elsif Clk'event and Clk = '1' then
if Rdy = '1' then
R_W_n <= not Write or RstCycle;
 
D <= (others => '1'); -- Dummy
PBR <= (others => '1'); -- Dummy
DBR <= (others => '1'); -- Dummy
EF_i <= '0'; -- Dummy
MF_i <= '0'; -- Dummy
XF_i <= '0'; -- Dummy
 
if MCycle = "000" then
Mode_r <= Mode;
 
if IRQCycle = '0' and NMICycle = '0' then
PC <= PC + 1;
end if;
 
if IRQCycle = '1' or NMICycle = '1' then
IR <= "00000000";
else
IR <= DI;
end if;
end if;
 
ALU_Op_r <= ALU_Op;
Write_Data_r <= Write_Data;
if Break = '1' then
Set_Addr_To_r <= "00";
else
Set_Addr_To_r <= Set_Addr_To;
end if;
 
if Inc_S = '1' then
S <= S + 1;
end if;
if Dec_S = '1' and RstCycle = '0' then
S <= S - 1;
end if;
if LDS = '1' then
S(7 downto 0) <= unsigned(ALU_Q);
end if;
 
if IR = "00000000" and MCycle = "001" and IRQCycle = '0' and NMICycle = '0' then
PC <= PC + 1;
end if;
case Jump is
when "01" =>
PC <= PC + 1;
when "10" =>
PC <= unsigned(DI & DL);
when "11" =>
if PCAdder(8) = '1' then
if DL(7) = '0' then
PC(15 downto 8) <= PC(15 downto 8) + 1;
else
PC(15 downto 8) <= PC(15 downto 8) - 1;
end if;
end if;
PC(7 downto 0) <= PCAdder(7 downto 0);
when others =>
end case;
end if;
end if;
end process;
 
process (Clk)
begin
if Clk'event and Clk = '1' then
if Rdy = '1' then
if MCycle = "000" then
if LDA = '1' then
ABC(7 downto 0) <= ALU_Q;
end if;
if LDX = '1' then
X(7 downto 0) <= ALU_Q;
end if;
if LDY = '1' then
Y(7 downto 0) <= ALU_Q;
end if;
if (LDA or LDX or LDY) = '1' then
P <= P_Out;
end if;
end if;
if SaveP = '1' then
P <= P_Out;
end if;
if LDP = '1' then
P <= ALU_Q;
end if;
if IR(4 downto 0) = "11000" then
case IR(7 downto 5) is
when "000" =>
P(Flag_C) <= '0';
when "001" =>
P(Flag_C) <= '1';
when "010" =>
P(Flag_I) <= '0';
when "011" =>
P(Flag_I) <= '1';
when "101" =>
P(Flag_V) <= '0';
when "110" =>
P(Flag_D) <= '0';
when "111" =>
P(Flag_D) <= '1';
when others =>
end case;
end if;
if IR = "00000000" and MCycle = "011" and RstCycle = '0' and NMICycle = '0' then
P(Flag_B) <= '1';
end if;
if IR = "00000000" and MCycle = "100" and RstCycle = '0' and NMICycle = '0' then
P(Flag_I) <= '1';
P(Flag_B) <= B_o;
end if;
if SO_n_o = '1' and SO_n = '0' then
P(Flag_V) <= '1';
end if;
if RstCycle = '1' and Mode_r /= "00" then
P(Flag_1) <= '1';
P(Flag_D) <= '0';
P(Flag_I) <= '1';
end if;
P(Flag_1) <= '1';
 
B_o <= P(Flag_B);
SO_n_o <= SO_n;
IRQ_n_o <= IRQ_n;
NMI_n_o <= NMI_n;
end if;
end if;
end process;
 
---------------------------------------------------------------------------
--
-- Buses
--
---------------------------------------------------------------------------
 
process (Res_n, Clk)
begin
if Res_n = '0' then
BusA_r <= (others => '0');
BusB <= (others => '0');
AD <= (others => '0');
BAL <= (others => '0');
BAH <= (others => '0');
DL <= (others => '0');
elsif Clk'event and Clk = '1' then
if Rdy = '1' then
BusA_r <= BusA;
BusB <= DI;
 
case BAAdd is
when "01" =>
-- BA Inc
AD <= std_logic_vector(unsigned(AD) + 1);
BAL <= std_logic_vector(unsigned(BAL) + 1);
when "10" =>
-- BA Add
BAL <= std_logic_vector(resize(unsigned(BAL(7 downto 0)),9) + resize(unsigned(BusA),9));
when "11" =>
-- BA Adj
if BAL(8) = '1' then
BAH <= std_logic_vector(unsigned(BAH) + 1);
end if;
when others =>
end case;
 
if ADAdd = '1' then
AD <= std_logic_vector(unsigned(AD) + unsigned(X(7 downto 0)));
end if;
 
if IR = "00000000" then
BAL <= (others => '1');
BAH <= (others => '1');
if RstCycle = '1' then
BAL(2 downto 0) <= "100";
elsif NMICycle = '1' then
BAL(2 downto 0) <= "010";
else
BAL(2 downto 0) <= "110";
end if;
if Set_addr_To_r = "11" then
BAL(0) <= '1';
end if;
end if;
 
 
if LDDI = '1' then
DL <= DI;
end if;
if LDALU = '1' then
DL <= ALU_Q;
end if;
if LDAD = '1' then
AD <= DI;
end if;
if LDBAL = '1' then
BAL(7 downto 0) <= DI;
end if;
if LDBAH = '1' then
BAH <= DI;
end if;
end if;
end if;
end process;
 
Break <= (BreakAtNA and not BAL(8)) or (PCAdd and not PCAdder(8));
 
PCAdder <= resize(PC(7 downto 0),9) + resize(unsigned(DL(7) & DL),9) when PCAdd = '1' else "0" & PC(7 downto 0);
 
with Set_BusA_To select
BusA <= DI when "000",
ABC(7 downto 0) when "001",
X(7 downto 0) when "010",
Y(7 downto 0) when "011",
std_logic_vector(S(7 downto 0)) when "100",
P when "101",
(others => '-') when others;
 
with Set_Addr_To_r select
A <= "0000000000000001" & std_logic_vector(S(7 downto 0)) when "01",
DBR & "00000000" & AD when "10",
"00000000" & BAH & BAL(7 downto 0) when "11",
PBR & std_logic_vector(PC(15 downto 8)) & std_logic_vector(PCAdder(7 downto 0)) when others;
 
with Write_Data_r select
DO <= DL when "000",
ABC(7 downto 0) when "001",
X(7 downto 0) when "010",
Y(7 downto 0) when "011",
std_logic_vector(S(7 downto 0)) when "100",
P when "101",
std_logic_vector(PC(7 downto 0)) when "110",
std_logic_vector(PC(15 downto 8)) when others;
 
-------------------------------------------------------------------------
--
-- Main state machine
--
-------------------------------------------------------------------------
 
process (Res_n, Clk)
begin
if Res_n = '0' then
MCycle <= "001";
RstCycle <= '1';
IRQCycle <= '0';
NMICycle <= '0';
NMIAct <= '0';
elsif Clk'event and Clk = '1' then
if Rdy = '1' then
if MCycle = LCycle or Break = '1' then
MCycle <= "000";
RstCycle <= '0';
IRQCycle <= '0';
NMICycle <= '0';
if NMIAct = '1' then
NMICycle <= '1';
elsif IRQ_n_o = '0' and P(Flag_I) = '0' then
IRQCycle <= '1';
end if;
else
MCycle <= std_logic_vector(unsigned(MCycle) + 1);
end if;
 
if NMICycle = '1' then
NMIAct <= '0';
end if;
if NMI_n_o = '1' and NMI_n = '0' then
NMIAct <= '1';
end if;
end if;
end if;
end process;
 
end;

powered by: WebSVN 2.1.0

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