📄 t65_mcode.vhd
字号:
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";
LCycle <= "010";
case to_integer(unsigned(MCycle)) is
when 1 =>
Jump <= "01";
LDDI <= '1';
when 2 =>
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 <= '0'; -- MIKEJ was 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
-- This circuit dictates when the last
-- microcycle occurs for the branch depending on
-- whether or not the branch is taken and if a page
-- is crossed...
if (Branch = '1') then
LCycle <= "011"; -- We're done @ T3 if branching...upper
-- level logic will stop at T2 if no page cross
-- (See the Break signal)
else
LCycle <= "001";
end if;
-- This decodes the current microcycle and takes the
-- proper course of action...
case to_integer(unsigned(MCycle)) is
-- On the T1 microcycle, increment the program counter
-- and instruct the upper level logic to fetch the offset
-- from the Din bus and store it in the data latches. This
-- will be the last microcycle if the branch isn't taken.
when 1 =>
Jump <= "01"; -- Increments the PC by one (PC will now be PC+2)
-- from microcycle T0.
LDDI <= '1'; -- Tells logic in top level (T65.vhd) to route
-- the Din bus to the memory data latch (DL)
-- so that the branch offset is fetched.
-- In microcycle T2, tell the logic in the top level to
-- add the offset. If the most significant byte of the
-- program counter (i.e. the current "page") does not need
-- updating, we are done here...the Break signal at the
-- T65.vhd level takes care of that...
when 2 =>
Jump <= "11"; -- Tell the PC Jump logic to use relative mode.
PCAdd <= '1'; -- This tells the PC adder to update itself with
-- the current offset recently fetched from
-- memory.
-- The following is microcycle T3 :
-- The program counter should be completely updated
-- on this cycle after the page cross is detected.
-- We don't need to do anything here...
when 3 =>
when others => null; -- Do nothing.
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';
-- Added this check for Y reg. use...
if (IR(3 downto 0) = "0110") then
AddY <= '1';
end if;
if IR(7 downto 5) = "100" then
Write <= '1';
end if;
Set_Addr_To <= "10"; -- AD
when 3 => null;
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";
-- mikej
-- special case 0xBE which uses Y reg as index!!
if (IR = "10111110") then
Set_BusA_To <= "011"; -- Y
else
Set_BusA_To <= "010"; -- X
end if;
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" => -- OR
--{{{
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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -