summaryrefslogtreecommitdiffstats
path: root/de1/fpga-bbc-pq/master/cpu-core-fixes.patch
diff options
context:
space:
mode:
Diffstat (limited to 'de1/fpga-bbc-pq/master/cpu-core-fixes.patch')
-rw-r--r--de1/fpga-bbc-pq/master/cpu-core-fixes.patch3881
1 files changed, 3881 insertions, 0 deletions
diff --git a/de1/fpga-bbc-pq/master/cpu-core-fixes.patch b/de1/fpga-bbc-pq/master/cpu-core-fixes.patch
new file mode 100644
index 0000000..4319a09
--- /dev/null
+++ b/de1/fpga-bbc-pq/master/cpu-core-fixes.patch
@@ -0,0 +1,3881 @@
+diff --git a/T65/T65.vhd b/T65/T65.vhd
+index 09253fe..bea8434 100644
+--- a/T65/T65.vhd
++++ b/T65/T65.vhd
+@@ -1,7 +1,20 @@
+ -- ****
+ -- T65(b) core. In an effort to merge and maintain bug fixes ....
+ --
++-- Ver 303 ost(ML) July 2014
++-- (Sorry for some scratchpad comments that may make little sense)
++-- Mods and some 6502 undocumented instructions.
+ --
++-- Not correct opcodes acc. to Lorenz tests (incomplete list):
++-- NOPN (nop)
++-- NOPZX (nop + byte 172)
++-- NOPAX (nop + word da ... da: byte 0)
++-- ASOZ (byte $07 + byte 172)
++--
++-- Wolfgang April 2014
++-- Ver 303 Bugfixes for NMI from foft
++-- Ver 302 Bugfix for BRK command
++-- Wolfgang January 2014
+ -- Ver 301 more merging
+ -- Ver 300 Bugfixes by ehenciak added, started tidyup *bust*
+ -- MikeJ March 2005
+@@ -69,345 +82,376 @@ library IEEE;
+ -- ehenciak 2-23-2005 : Added the enable signal so that one doesn't have to use
+ -- the ready signal to limit the CPU.
+ entity T65 is
+- port(
+- Mode : in std_logic_vector(1 downto 0); -- "00" => 6502, "01" => 65C02, "10" => 65C816
+- Res_n : in std_logic;
+- Enable : 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)
+- );
++ port(
++ Mode : in std_logic_vector(1 downto 0); -- "00" => 6502, "01" => 65C02, "10" => 65C816
++ Res_n : in std_logic;
++ Enable : 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);--NOTE:Make sure DI equals DO when writing. This is important for DCP/DCM undoc instruction. TODO:convert to inout
++ DO : out std_logic_vector(7 downto 0);
++ -- 6502 registers (MSB) PC, SP, P, Y, X, A (LSB)
++ Regs : out std_logic_vector(63 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) := x"00";
+- 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 AddY : 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;
+-
+- signal really_rdy : std_logic;
+- signal R_W_n_i : std_logic;
++ -- Registers
++ signal ABC, X, Y, D : std_logic_vector(15 downto 0);
++ signal P, AD, DL : std_logic_vector(7 downto 0) := x"00";
++ signal PwithB : std_logic_vector(7 downto 0);--ML:New way to push P with correct B state to stack
++ 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 : T_ALU_Op;
++ signal Write_Data_r : T_Write_Data;
++ signal Set_Addr_To_r : T_Set_Addr_To;
++ signal PCAdder : unsigned(8 downto 0);
++
++ signal RstCycle : std_logic;
++ signal IRQCycle : std_logic;
++ signal NMICycle : 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 : T_ALU_Op;
++ signal Set_BusA_To : T_Set_BusA_To;
++ signal Set_Addr_To : T_Set_Addr_To;
++ signal Write_Data : T_Write_Data;
++ 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 AddY : 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;
++ signal ALUmore : std_logic;
++
++ signal really_rdy : std_logic;
++ signal R_W_n_i : std_logic;
++ signal R_W_n_i_d : std_logic;
++
++ signal NMIActClear : std_logic; -- MWW hack
+
+ begin
+- -- ehenciak : gate Rdy with read/write to make an "OK, it's
+- -- really OK to stop the processor now if Rdy is
+- -- deasserted" signal
+- really_rdy <= Rdy or not(R_W_n_i);
+-
+- -- ehenciak : Drive R_W_n_i off chip.
+- R_W_n <= R_W_n_i;
+-
+- 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 /= "00" 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,
+- AddY => AddY,
+- 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_i <= '1';
+- EF_i <= '1';
+- MF_i <= '1';
+- XF_i <= '1';
+-
+- elsif Clk'event and Clk = '1' then
+- if (Enable = '1') then
+- if (really_rdy = '1') then
+- R_W_n_i <= 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;
+- --
+- -- jump control logic
+- --
+- 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 => null;
+- end case;
+- end if;
+- end if;
+- end if;
+- end process;
+-
+- PCAdder <= resize(PC(7 downto 0),9) + resize(unsigned(DL(7) & DL),9) when PCAdd = '1'
+- else "0" & PC(7 downto 0);
+-
+- process (Clk)
+- begin
+- if Clk'event and Clk = '1' then
+- if (Enable = '1') then
+- if (really_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' and IRQCycle = '0' then
+- -- P(Flag_B) <= '1';
+- --end if;
+- --if IR = "00000000" and MCycle = "100" and RstCycle = '0' and (NMICycle = '1' or IRQCycle = '1') then
+- -- P(Flag_I) <= '1';
+- -- P(Flag_B) <= B_o;
+- --end if;
+-
+- -- B=1 always on the 6502
+- P(Flag_B) <= '1';
+- if IR = "00000000" and RstCycle = '0' and (NMICycle = '1' or IRQCycle = '1') then
+- if MCycle = "011" then
+- -- B=0 in *copy* of P pushed onto the stack
+- P(Flag_B) <= '0';
+- elsif MCycle = "100" then
+- P(Flag_I) <= '1';
++ -- workaround for ready-handling
++ -- ehenciak : Drive R_W_n_i off chip.
++ R_W_n <= R_W_n_i;
++
++ -- ehenciak : gate Rdy with read/write to make an "OK, it's
++ -- really OK to stop the processor now if Rdy is
++ -- deasserted" signal
++ really_rdy <= Rdy or not(R_W_n_i);
++ ----
++
++ 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 /= Set_Addr_To_PBR else '0'; -- Incorrect !!!!!!!!!!!!
++ VPA <= '1' when Jump(1) = '0' else '0'; -- Incorrect !!!!!!!!!!!!
++
++ Regs <= std_logic_vector(PC) & std_logic_vector(S)& P & Y(7 downto 0) & X(7 downto 0) & ABC(7 downto 0);
++
++ mcode : T65_MCode
++ port map(
++--inputs
++ Mode => Mode_r,
++ IR => IR,
++ MCycle => MCycle,
++ P => P,
++--outputs
++ 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,
++ AddY => AddY,
++ 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,
++ ALUmore => ALUmore,
++ 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 <= ALU_OP_BIT;
++ Write_Data_r <= Write_Data_DL;
++ Set_Addr_To_r <= Set_Addr_To_PBR;
++
++ R_W_n_i <= '1';
++ EF_i <= '1';
++ MF_i <= '1';
++ XF_i <= '1';
++
++ elsif Clk'event and Clk = '1' then
++ if (Enable = '1') then
++ if (really_rdy = '1') then
++ R_W_n_i <= 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 <= Set_Addr_To_PBR;
++ 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;
+- 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 if;
+- end process;
++ --
++ -- jump control logic
++ --
++ 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 => null;
++ end case;
++ end if;
++ end if;
++ end if;
++ end process;
++
++ PCAdder <= resize(PC(7 downto 0),9) + resize(unsigned(DL(7) & DL),9) when PCAdd = '1'
++ else "0" & PC(7 downto 0);
++
++ process (Res_n, Clk)
++ variable tmpP:std_logic_vector(7 downto 0);--ML:Lets try to handle loading P at mcycle=0 and set/clk flags at same cycle
++ begin
++ if Res_n = '0' then
++ P <= x"00"; -- ensure we have nothing set on reset (e.g. B flag!)
++ elsif Clk'event and Clk = '1' then
++ tmpP:=P;
++ if (Enable = '1') then
++ if (really_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;-- Replaced with:
++ tmpP:=P_Out;
++ end if;
++ end if;
++ if SaveP = '1' then
++-- P <= P_Out;-- Replaced with:
++ tmpP:=P_Out;
++ end if;
++ if LDP = '1' then
++-- P <= ALU_Q;-- Replaced with: --ML:no need anymore: AND x"EF"; -- NEVER set B on RTI and PLP
++ tmpP:=ALU_Q;
++ end if;
++ if IR(4 downto 0) = "11000" then
++ case IR(7 downto 5) is
++ when "000" =>--0x18(clc)
++-- P(Flag_C) <= '0';-- Replaced with:
++ tmpP(Flag_C) := '0';
++ when "001" =>--0x38(sec)
++-- P(Flag_C) <= '1';
++ tmpP(Flag_C) := '1';
++ when "010" =>--0x58(cli)
++-- P(Flag_I) <= '0';
++ tmpP(Flag_I) := '0';
++ when "011" =>--0x78(sei)
++-- P(Flag_I) <= '1';
++ tmpP(Flag_I) := '1';
++ when "101" =>--0xb8(clv)
++-- P(Flag_V) <= '0';
++ tmpP(Flag_V) := '0';
++ when "110" =>--0xd8(cld)
++-- P(Flag_D) <= '0';
++ tmpP(Flag_D) := '0';
++ when "111" =>--0xf8(sed)
++-- P(Flag_D) <= '1';
++ tmpP(Flag_D) := '1';
++ when others =>
++ end case;
++ end if;
++ --ML:Removed change of B flag, its constant '1' in P
++ --ML:The B flag appears to be locked to '1', but when pushed to stack, the SR data on the stack has the B flag cleared on interrupts, set on BRK instr.
++ --ML:The state of the B flag on warm reset apparently is unchanged (not confirmed, please do if you know)
++ --ML:The state of the B flag on cold reset is uncertain, but my guess would be set, unless it can be used to detect cold from warm reset.
++ --Since we cant (well, won't) simulate B=0 on cold reset, we just behave as if it was constant 1.
++-- P(Flag_B) <= '1';
++ tmpP(Flag_B) := '1';
++-- if IR = "00000000" and MCycle = "011" and RstCycle = '0' and NMICycle = '0' and IRQCycle = '0' then -- BRK
++-- P(Flag_B) <= '1';
++-- elsif IR = "00001000" then -- PHP
++-- P(Flag_B) <= '1';
++-- else
++-- P(Flag_B) <= '0'; --> not the best way, but we keep B zero except for BRK and PHP opcodes
++-- end if;
++ if IR = "00000000" and MCycle = "100" and RstCycle = '0' then --and (NMICycle = '1' or IRQCycle = '1') then
++ --This should happen after P has been pushed to stack
++-- P(Flag_I) <= '1';
++ tmpP(Flag_I) := '1';
++ end if;
++ if SO_n_o = '1' and SO_n = '0' then
++-- P(Flag_V) <= '1';
++ tmpP(Flag_V) := '1';
++ end if;
++ if RstCycle = '1' then
++-- P(Flag_I) <= '0';
++-- P(Flag_D) <= '0';
++ tmpP(Flag_I) := '1';
++ tmpP(Flag_D) := '0';
++ end if;
++-- P(Flag_1) <= '1';
++ tmpP(Flag_1) := '1';
++
++ P<=tmpP;--new way
++
++ SO_n_o <= SO_n;
++ IRQ_n_o <= IRQ_n;
++ end if;
++ NMI_n_o <= NMI_n; -- MWW: detect nmi even if not rdy
++ end if;
++ end if;
++ end process;
+
+ ---------------------------------------------------------------------------
+ --
+@@ -415,109 +459,125 @@ begin
+ --
+ ---------------------------------------------------------------------------
+
+- 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 (Enable = '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;
+-
+- -- ehenciak : modified to use Y register as well (bugfix)
+- if ADAdd = '1' then
+- if (AddY = '1') then
+- AD <= std_logic_vector(unsigned(AD) + unsigned(Y(7 downto 0)));
+- else
+- AD <= std_logic_vector(unsigned(AD) + unsigned(X(7 downto 0)));
+- end if;
+- 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 if;
+- end process;
+-
+- Break <= (BreakAtNA and not BAL(8)) or (PCAdd and not PCAdder(8));
+-
+-
+- 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;
++ 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 (Enable = '1') then
++ if (really_rdy = '1') then
++ --if (Rdy = '1') then
++ BusA_r <= BusA;
++ if ALUmore='1' then
++ BusB <= ALU_Q;
++ else
++ BusB <= DI;
++ end if;
++
++ 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;
++
++ -- ehenciak : modified to use Y register as well (bugfix)
++ if ADAdd = '1' then
++ if (AddY = '1') then
++ AD <= std_logic_vector(unsigned(AD) + unsigned(Y(7 downto 0)));
++ else
++ AD <= std_logic_vector(unsigned(AD) + unsigned(X(7 downto 0)));
++ end if;
++ end if;
++
++ NMIActClear <= '0';
++ 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";
++ elsif NMIAct = '1' then -- MWW, force this to be changed by NMI, even if in midstream IRQ/brk
++ BAL(2 downto 0) <= "010";
++ NMIActClear <= '1';
++ else
++ BAL(2 downto 0) <= "110";
++ end if;
++ if Set_addr_To_r = Set_Addr_To_BA 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 if;
++ end process;
++
++ Break <= (BreakAtNA and not BAL(8)) or (PCAdd and not PCAdder(8));
++
++ with Set_BusA_To select
++ BusA <=
++ DI when Set_BusA_To_DI,
++ ABC(7 downto 0) when Set_BusA_To_ABC,
++ X(7 downto 0) when Set_BusA_To_X,
++ Y(7 downto 0) when Set_BusA_To_Y,
++ std_logic_vector(S(7 downto 0)) when Set_BusA_To_S,
++ P when Set_BusA_To_P,
++ (others => '-') when Set_BusA_To_DONTCARE;--Can probably remove this
++
++ with Set_Addr_To_r select
++ A <=
++ "0000000000000001" & std_logic_vector(S(7 downto 0)) when Set_Addr_To_S,
++ DBR & "00000000" & AD when Set_Addr_To_AD,
++ "00000000" & BAH & BAL(7 downto 0) when Set_Addr_To_BA,
++ PBR & std_logic_vector(PC(15 downto 8)) & std_logic_vector(PCAdder(7 downto 0)) when Set_Addr_To_PBR;
++
++ --ML:This is the P that gets pushed on stack with correct B flag. I'm not sure if NMI also clears B, but I guess it does.
++ PwithB<=(P and x"ef") when (IRQCycle='1' or NMICycle='1') else P;
++
++ with Write_Data_r select
++ DO <=
++ DL when Write_Data_DL,
++ ABC(7 downto 0) when Write_Data_ABC,
++ X(7 downto 0) when Write_Data_X,
++ Y(7 downto 0) when Write_Data_Y,
++ std_logic_vector(S(7 downto 0)) when Write_Data_S,
++ PwithB when Write_Data_P,
++ std_logic_vector(PC(7 downto 0)) when Write_Data_PCL,
++ std_logic_vector(PC(15 downto 8)) when Write_Data_PCH,
++ (others=>'-') when Write_Data_DONTCARE;--Can probably remove this
++
+
+ -------------------------------------------------------------------------
+ --
+@@ -525,40 +585,44 @@ begin
+ --
+ -------------------------------------------------------------------------
+
+- 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 (Enable = '1') then
+- if (really_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 if;
+- end process;
++ 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 (Enable = '1') then
++ if (really_rdy = '1') then
++ if (NMIActClear = '1') then
++ NMIAct <= '0';
++ end if;
++
++ 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;
++ end if;
++ if NMI_n_o = '1' and NMI_n = '0' then -- MWW: detect nmi even if not rdy
++ NMIAct <= '1';
++ end if;
++ end if;
++ end if;
++ end process;
+
+ end;
+diff --git a/T65/T65_ALU.vhd b/T65/T65_ALU.vhd
+index b1f6d63..49ae4a1 100644
+--- a/T65/T65_ALU.vhd
++++ b/T65/T65_ALU.vhd
+@@ -2,6 +2,8 @@
+ -- T65(b) core. In an effort to merge and maintain bug fixes ....
+ --
+ --
++-- Ver 303 ost(ML) July 2014
++-- ALU opcodes to vhdl types
+ -- Ver 300 Bugfixes by ehenciak added
+ -- MikeJ March 2005
+ -- Latest version from www.fpgaarcade.com (original www.opencores.org)
+@@ -62,199 +64,201 @@ 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)
+- );
++ port(
++ Mode : in std_logic_vector(1 downto 0); -- "00" => 6502, "01" => 65C02, "10" => 65816
++ Op : in T_ALU_OP;
++ 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);
++ -- 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);
++ 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;
++ 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(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;
++ 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);
++ 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));
++ 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;
++ 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;
++ 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_C <= AH(6) or AH(5);
+
+- ADC_Q <= std_logic_vector(AH(4 downto 1) & AL(4 downto 1));
+- end process;
++ 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);
++ process (Op, P_In, BusA, BusB)
++ variable AL : unsigned(6 downto 0);
++ variable AH : unsigned(5 downto 0);
++ variable C : std_logic;
++ variable CT : std_logic;
++ begin
++ CT:='0';
++ if( Op=ALU_OP_AND or --"0001" These OpCodes used to have LSB set
++ Op=ALU_OP_ADC or --"0011"
++ Op=ALU_OP_EQ2 or --"0101"
++ Op=ALU_OP_SBC or --"0111"
++ Op=ALU_OP_ROL or --"1001"
++ Op=ALU_OP_ROR or --"1011"
++ Op=ALU_OP_EQ3 or --"1101"
++ Op=ALU_OP_INC --"1111"
++ ) then
++ CT:='1';
++ end if;
++
++ C := P_In(Flag_C) or not CT;--was: 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;
++ 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;
++ 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);
++ 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;
++ 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;
++ 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;
++ 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 is
++ when ALU_OP_OR=>
++ Q_t := BusA or BusB;
++ when ALU_OP_AND=>
++ Q_t := BusA and BusB;
++ when ALU_OP_EOR=>
++ Q_t := BusA xor BusB;
++ when ALU_OP_ADC=>
++ P_Out(Flag_V) <= ADC_V;
++ P_Out(Flag_C) <= ADC_C;
++ Q_t := ADC_Q;
++ when ALU_OP_EQ2|ALU_OP_EQ3=>
++ -- LDA
++ when ALU_OP_CMP=>
++ P_Out(Flag_C) <= SBC_C;
++ when ALU_OP_SBC=>
++ P_Out(Flag_V) <= SBC_V;
++ P_Out(Flag_C) <= SBC_C;
++ Q_t := SBC_Q;
++ when ALU_OP_ASL=>
++ Q_t := BusA(6 downto 0) & "0";
++ P_Out(Flag_C) <= BusA(7);
++ when ALU_OP_ROL=>
++ Q_t := BusA(6 downto 0) & P_In(Flag_C);
++ P_Out(Flag_C) <= BusA(7);
++ when ALU_OP_LSR=>
++ Q_t := "0" & BusA(7 downto 1);
++ P_Out(Flag_C) <= BusA(0);
++ when ALU_OP_ROR=>
++ Q_t := P_In(Flag_C) & BusA(7 downto 1);
++ P_Out(Flag_C) <= BusA(0);
++ when ALU_OP_BIT=>
++ P_Out(Flag_V) <= BusB(6);
++ when ALU_OP_DEC=>
++ Q_t := std_logic_vector(unsigned(BusA) - 1);
++ when ALU_OP_INC=>
++ Q_t := std_logic_vector(unsigned(BusA) + 1);
++ when others =>
++ --EQ1,EQ2,EQ3 passes BusA to Q_t
++ 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;
++ case Op is
++ when ALU_OP_ADC=>
++ P_Out(Flag_N) <= ADC_N;
++ P_Out(Flag_Z) <= ADC_Z;
++ when ALU_OP_CMP|ALU_OP_SBC=>
++ P_Out(Flag_N) <= SBC_N;
++ P_Out(Flag_Z) <= SBC_Z;
++ when ALU_OP_EQ1=>
++ when ALU_OP_BIT=>
++ 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;
++ Q <= Q_t;
++ end process;
+
+ end;
+diff --git a/T65/T65_MCode.vhd b/T65/T65_MCode.vhd
+index 6c6c864..bfc4005 100644
+--- a/T65/T65_MCode.vhd
++++ b/T65/T65_MCode.vhd
+@@ -2,9 +2,17 @@
+ -- T65(b) core. In an effort to merge and maintain bug fixes ....
+ --
+ --
++-- Ver 303 ost(ML) July 2014
++-- (Sorry for some scratchpad comments that may make little sense)
++-- Mods and some 6502 undocumented instructions.
++-- Undoc opcodes learnt from:
++-- "Extra Instructions Of The 65XX Series CPU"
++-- By: Adam Vardy (abe0084@infonet.st-johns.nf.ca)
++-- [File created: 22, Aug. 1995... 27, Sept. 1996]
+ -- Ver 302 minor timing fixes
+ -- Ver 301 Jump timing fixed
+ -- Ver 300 Bugfixes by ehenciak added
++-- Wolfgang January 2014
+ -- MikeJ March 2005
+ -- Latest version from www.fpgaarcade.com (original www.opencores.org)
+ --
+@@ -65,988 +73,1324 @@
+ library IEEE;
+ use IEEE.std_logic_1164.all;
+ use IEEE.numeric_std.all;
++use ieee.std_logic_unsigned.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;
+- AddY : 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
+- );
++ 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 T_ALU_Op;
++ Set_BusA_To : out T_Set_BusA_To;-- DI,A,X,Y,S,P
++ Set_Addr_To : out T_Set_Addr_To;-- PC Adder,S,AD,BA
++ Write_Data : out T_Write_Data;-- DL,A,X,Y,S,P,PCL,PCH,A&X
++ 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;
++ AddY : 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;
++ ALUmore : out std_logic;
++ Write : out std_logic
++ );
+ end T65_MCode;
+
+ architecture rtl of T65_MCode is
+
+- signal Branch : std_logic;
++ signal Branch : std_logic;
++ --ML:I need the Lcycle locally, so I made it a signal.
++ signal tLcycle:std_logic_vector(Lcycle'range);
++ signal tALUmore:std_logic;
++
++ --Some simulation debug values. Put an unique number for each assignment and identify it in simulation.
++ signal dbg_Set_BusA_To :integer:=0; --sim debug value to find where Set_BusA_To gets set.
++ signal dbg_LCycle :integer:=0; --sim debug value to fin where tLCycle gets set.
++ signal dbg_Set_Addr_To :integer:=0; --sim debug value to fin where Set_Addr_To gets set.
+
+ 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;
++ 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';
+- AddY <= '0';
++ LCycle<=tLCycle;
++ ALUmore<=tALUmore;
+
+- 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;
++ process (IR, MCycle, P, Branch, Mode,tALUmore)
++ begin
++ tLCycle <= "001";
++ Set_BusA_To <= Set_BusA_To_ABC;
++ Set_Addr_To <= Set_Addr_To_PBR;
++ Write_Data <= Write_Data_DL;
++ 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';
++ AddY <= '0';
++ tALUmore <='0';
++
++ case IR(7 downto 5) is
++ when "100" =>--covers 8x,9x
++ --{{{
++ case IR(1 downto 0) is
++ when "00" =>
++ Set_BusA_To <= Set_BusA_To_Y;
++ dbg_Set_BusA_To<=1;
++ Write_Data <= Write_Data_Y;
++ when "10" =>
++ Set_BusA_To <= Set_BusA_To_X;
++ dbg_Set_BusA_To<=2;
++ Write_Data <= Write_Data_X;
++ when others =>
++ Write_Data <= Write_Data_ABC;
++ end case;
++ --}}}
++ when "101" =>--covers ax,bx
++ --{{{
++ case IR(1 downto 0) is
++ when "00" =>
++ if IR(4) /= '1' or IR(2) /= '0' then--only for ax or b4,bc
++ LDY <= '1';
++ end if;
++ when "10" =>
++ LDX <= '1';
++ when "11" =>--undoc (beware OAL(ab),LAS(bb)=>Dont know what will happen)
++ LDX<='1';
++ LDA<='1';
++ when others =>
++ LDA <= '1';
++ end case;
++ Set_BusA_To <= Set_BusA_To_DI;
++ dbg_Set_BusA_To<=4;
++ --}}}
++ when "110" =>--covers cx,dx
++ --{{{
++ case IR(1 downto 0) is
++ when "00" =>
++ if IR(4) = '0' then--only for cx
++ LDY <= '1';
++ end if;
++ Set_BusA_To <= Set_BusA_To_Y;
++ dbg_Set_BusA_To<=5;
++ when others =>
++ Set_BusA_To <= Set_BusA_To_ABC;
++ dbg_Set_BusA_To<=6;
++ end case;
++ --}}}
++ when "111" =>--covers ex,fx
++ --{{{
++ case IR(1 downto 0) is
++ when "00" =>
++ if IR(4) = '0' then--only ex
++ LDX <= '1';
++ end if;
++ Set_BusA_To <= Set_BusA_To_X;
++ dbg_Set_BusA_To<=7;
++ when others =>
++ Set_BusA_To <= Set_BusA_To_ABC;
++ dbg_Set_BusA_To<=8;
++ 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;
++-- if IR(7 downto 6) /= "10" and IR(1 downto 0) = "10" then--covers 0x-7x,cx-fx x=2,6,a,e
++ if IR(7 downto 6) /= "10" and IR(1) = '1' and (mode="00" or IR(0)='0') then--covers 0x-7x,cx-fx x=2,3,6,7,a,b,e,f, for 6502 undocs
++-- if Mode="00" and IR(0)='1' and ((IR(3 downto 2)="11" and MCycle = "101") or (IR(3 downto 2)="01" and MCycle = "100"))then
++ --if Mode="00" and IR(0)='1' and MCycle+1 = tLCycle then
++ if tALUmore='1' then
++ Set_BusA_To <= Set_BusA_To_ABC;--For added compare to DCP/DCM
++ dbg_Set_BusA_To<=99;
++ else
++ Set_BusA_To <= Set_BusA_To_DI;
++ dbg_Set_BusA_To<=9;
++ end if;
++ 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;
++ case IR(4 downto 0) is
++ when "00000" | "01000" | "01010" | "11000" | "11010" =>
++ --{{{
++ -- Implied
++ case IR is
++ when "00000000" =>
++ -- BRK
++ tLCycle <= "110";
++ dbg_LCycle<=1;
++ case to_integer(unsigned(MCycle)) is
++ when 1 =>
++ Set_Addr_To <= Set_Addr_To_S;
++ dbg_Set_Addr_To<=1;
++ Write_Data <= Write_Data_PCH;
++ Write <= '1';
++ when 2 =>
++ Dec_S <= '1';
++ Set_Addr_To <= Set_Addr_To_S;
++ dbg_Set_Addr_To<=2;
++ Write_Data <= Write_Data_PCL;
++ Write <= '1';
++ when 3 =>
++ Dec_S <= '1';
++ Set_Addr_To <= Set_Addr_To_S;
++ dbg_Set_Addr_To<=3;
++ Write_Data <= Write_Data_P;
++ Write <= '1';
++ when 4 =>
++ Dec_S <= '1';
++ Set_Addr_To <= Set_Addr_To_BA;
++ dbg_Set_Addr_To<=4;
++ when 5 =>
++ LDDI <= '1';
++ Set_Addr_To <= Set_Addr_To_BA;
++ dbg_Set_Addr_To<=5;
++ when 6 =>
++ Jump <= "10"; -- DIDL
++ when others =>
++ end case;
++ when "00100000" =>
++ -- JSR
++ tLCycle <= "101";
++ dbg_LCycle<=2;
++ case to_integer(unsigned(MCycle)) is
++ when 1 =>
++ Jump <= "01";
++ LDDI <= '1';
++ Set_Addr_To <= Set_Addr_To_S;
++ dbg_Set_Addr_To<=6;
++ when 2 =>
++ Set_Addr_To <= Set_Addr_To_S;
++ dbg_Set_Addr_To<=7;
++ Write_Data <= Write_Data_PCH;
++ Write <= '1';
++ when 3 =>
++ Dec_S <= '1';
++ Set_Addr_To <= Set_Addr_To_S;
++ dbg_Set_Addr_To<=8;
++ Write_Data <= Write_Data_PCL;
++ Write <= '1';
++ when 4 =>
++ Dec_S <= '1';
++ when 5 =>
++ Jump <= "10"; -- DIDL
++ when others =>
++ end case;
++ when "01000000" =>
++ -- RTI
++ tLCycle <= "101";
++ dbg_LCycle<=3;
++ case to_integer(unsigned(MCycle)) is
++ when 1 =>
++ Set_Addr_To <= Set_Addr_To_S;
++ dbg_Set_Addr_To<=9;
++ when 2 =>
++ Inc_S <= '1';
++ Set_Addr_To <= Set_Addr_To_S;
++ dbg_Set_Addr_To<=10;
++ when 3 =>
++ Inc_S <= '1';
++ Set_Addr_To <= Set_Addr_To_S;
++ dbg_Set_Addr_To<=11;
++ Set_BusA_To <= Set_BusA_To_DI;
++ dbg_Set_BusA_To<=10;
++ when 4 =>
++ LDP <= '1';
++ Inc_S <= '1';
++ LDDI <= '1';
++ Set_Addr_To <= Set_Addr_To_S;
++ dbg_Set_Addr_To<=12;
++ when 5 =>
++ Jump <= "10"; -- DIDL
++ when others =>
++ end case;
++ when "01100000" =>
++ -- RTS
++ tLCycle <= "101";
++ dbg_LCycle<=4;
++ case to_integer(unsigned(MCycle)) is
++ when 1 =>
++ Set_Addr_To <= Set_Addr_To_S;
++ dbg_Set_Addr_To<=13;
++ when 2 =>
++ Inc_S <= '1';
++ Set_Addr_To <= Set_Addr_To_S;
++ dbg_Set_Addr_To<=14;
++ when 3 =>
++ Inc_S <= '1';
++ LDDI <= '1';
++ Set_Addr_To <= Set_Addr_To_S;
++ dbg_Set_Addr_To<=15;
++ when 4 =>
++ Jump <= "10"; -- DIDL
++ when 5 =>
++ Jump <= "01";
++ when others =>
++ end case;
++ when "00001000" | "01001000" | "01011010" | "11011010" =>
++ -- PHP, PHA, PHY*, PHX*
++ tLCycle <= "010";
++ dbg_LCycle<=5;
++ if Mode = "00" and IR(1) = '1' then--2 cycle nop
++ tLCycle <= "001";
++ dbg_LCycle<=6;
++ end if;
++ case to_integer(unsigned(MCycle)) is
++ when 1 =>
++ if mode/="00" or IR(1)='0' then --wrong on 6502
++ Write <= '1';
++ case IR(7 downto 4) is
++ when "0000" =>
++ Write_Data <= Write_Data_P;
++ when "0100" =>
++ Write_Data <= Write_Data_ABC;
++ when "0101" => --not correct unsupporte
++ if Mode /= "00" then
++ Write_Data <= Write_Data_Y;
++ else
++ Write <= '0';
++ end if;
++ when "1101" =>
++ if Mode /= "00" then
++ Write_Data <= Write_Data_X;
++ else
++ Write <= '0';
++ end if;
++ when others =>
++ end case;
++ Set_Addr_To <= Set_Addr_To_S;
++ dbg_Set_Addr_To<=16;
++ end if;
++ when 2 =>
++ Dec_S <= '1';
++ when others =>
++ end case;
++ when "00101000" | "01101000" | "01111010" | "11111010" =>
++ -- PLP, PLA, PLY*, PLX*
++ tLCycle <= "011";
++ dbg_LCycle<=7;
++ if Mode = "00" and IR(1) = '1' then--2 cycle nop
++ tLCycle <= "001";
++ dbg_LCycle<=8;
++ end if;
++ case IR(7 downto 4) is
++ when "0010" =>--plp
++ LDP <= '1';
++ when "0110" =>--pla
++ LDA <= '1';
++ when "0111" =>--ply not for 6502
++ if Mode /= "00" then
++ LDY <= '1';
++ end if;
++ when "1111" =>--plx not for 6502
++ if Mode /= "00" then
++ LDX <= '1';
++ end if;
++ 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;
+- --}}}
++ case to_integer(unsigned(MCycle)) is
++ when 0 =>
++ if Mode /= "00" or IR(1) = '0' then--wrong on 6502
++ SaveP <= '1';
++ end if;
++ when 1 =>
++ if Mode /= "00" or IR(1) = '0' then--wrong on 6502
++ Set_Addr_To <= Set_Addr_To_S;
++ dbg_Set_Addr_To<=17;
++ -- MWW This is wrong, ALU_OP is not populated yet, so previous op's P_out can be saved (This was caused by ROL followed by PLA - THE ISSUE MAY BE DEEPER!)
++ --SaveP <= '1'; --MWW
++ LDP <= '0';--MWW
++ end if;
++ when 2 =>
++ Inc_S <= '1';
++ Set_Addr_To <= Set_Addr_To_S;
++ dbg_Set_Addr_To<=18;
++ --SaveP <= '1';--MWW
++ LDP <= '0'; --MWW
++ when 3 =>
++ Set_BusA_To <= Set_BusA_To_DI;
++ dbg_Set_BusA_To<=11;
++ 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 <= Set_BusA_To_Y;
++ dbg_Set_BusA_To<=12;
++ when others =>
++ end case;
++ when "11001010" =>
++ -- DEX
++ LDX <= '1';
++ case to_integer(unsigned(MCycle)) is
++ when 0 =>
++ when 1 =>
++ Set_BusA_To <= Set_BusA_To_X;
++ dbg_Set_BusA_To<=13;
++ when others =>
++ end case;
++ when "00011010" | "00111010" =>
++ -- INC*, DEC*
++ if Mode /= "00" then
++ LDA <= '1'; -- A
++ else
++ tLCycle <= "001";--undoc 2 cycle nop..can I just load tLCycle counter like this?
++ dbg_LCycle<=9;
++ end if;
++ case to_integer(unsigned(MCycle)) is
++ when 0 =>
++ when 1 =>
++ Set_BusA_To <= Set_BusA_To_S;
++ dbg_Set_BusA_To<=14;
++ when others =>
++ end case;
++ when "00001010" | "00101010" | "01001010" | "01101010" =>
++ -- ASL, ROL, LSR, ROR
++ LDA <= '1'; -- A
++ Set_BusA_To <= Set_BusA_To_ABC;
++ dbg_Set_BusA_To<=15;
++ 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 <= Set_BusA_To_ABC;
++ dbg_Set_BusA_To<=16;
++ 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 <= Set_BusA_To_S;
++ dbg_Set_BusA_To<=17;
++ when others =>
++ 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 "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 "01001" | "01011" =>
+- --{{{
+- -- Immediate
+- LDA <= '1';
+- case to_integer(unsigned(MCycle)) is
+- when 0 =>
+- when 1 =>
+- Jump <= "01";
+- when others =>
+- end case;
++ when "00001" | "00011" =>
++ --{{{
++ -- Zero Page Indexed Indirect (d,x)
++ tLCycle <= "101";
++ dbg_LCycle<=10;
++ if IR(7 downto 6) /= "10" then
++ LDA <= '1';
++ if Mode="00" and IR(1)='1' then--b3
++ LDX <= '1';--undoc, can load both A and X
++ end if;
++ end if;
++ case to_integer(unsigned(MCycle)) is
++ when 1 =>
++ Jump <= "01";
++ LDAD <= '1';
++ Set_Addr_To <= Set_Addr_To_AD;
++ dbg_Set_Addr_To<=19;
++ when 2 =>
++ ADAdd <= '1';
++ Set_Addr_To <= Set_Addr_To_AD;
++ dbg_Set_Addr_To<=20;
++ when 3 =>
++ BAAdd <= "01"; -- DB Inc
++ LDBAL <= '1';
++ Set_Addr_To <= Set_Addr_To_AD;
++ dbg_Set_Addr_To<=21;
++ when 4 =>
++ LDBAH <= '1';
++ if IR(7 downto 5) = "100" then
++ Write <= '1';
++ end if;
++ Set_Addr_To <= Set_Addr_To_BA;
++ dbg_Set_Addr_To<=22;
++ when 5 =>
++ if Mode="00" and IR(1)='1' then
++ tALUmore <= '1';--ML:For undoc ASO support
++ end if;
++ when 0 =>
++ if Mode="00" and IR(1)='1' then
++ SaveP <= '1';--ML:For undoc DCP/DCM support, save again after compare
++ end if;
++ 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 "00010" | "10010" =>
++ --{{{
++ -- Immediate, SKB, KIL
+
+- 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;
+- --}}}
++ case to_integer(unsigned(MCycle)) is
++ when 0 =>
++ when 1 =>
++ if IR = "10100010" then
++ -- LDX
++ Jump <= "01";
++ LDX <= '1';--ML:Moved, Lorenz test showed X changing on SKB (NOPx)
++ elsif IR(7 downto 4)="1000" or IR(7 downto 4)="1100" or IR(7 downto 4)="1110" then
++ -- SKB skip next byte undoc
++ else
++ -- KIL !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
++ end if;
++ when others =>
++ end case;
++ --}}}
+
+- 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";
+- LCycle <= "100"; -- mikej
+- case to_integer(unsigned(MCycle)) is
+- when 1 =>
+- Jump <= "01";
+- LDDI <= '1';
+- LDBAL <= '1';
+- when 2 =>
+- LDBAH <= '1';
+- if Mode /= "00" then
+- Jump <= "10"; -- DIDL
+- end if;
+- if Mode = "00" then
+- Set_Addr_To <= "11"; -- BA
+- end if;
+- when 3 =>
+- LDDI <= '1';
+- if Mode = "00" then
+- Set_Addr_To <= "11"; -- BA
+- BAAdd <= "01"; -- DB Inc
+- else
+- Jump <= "01";
+- end if;
+- when 4 =>
+- 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 "00100" =>
++ --{{{
++ -- Zero Page
++ tLCycle <= "010";
++ dbg_LCycle<=11;
++ case to_integer(unsigned(MCycle)) is
++ when 0 =>
++ if IR(7 downto 5) = "001" then--24=BIT zpg
++ SaveP <= '1';
++ end if;
++ when 1 =>
++ Jump <= "01";
++ LDAD <= '1';
++ if IR(7 downto 5) = "100" then--84=sty zpg (the only write in this group)
++ Write <= '1';
++ end if;
++ Set_Addr_To <= Set_Addr_To_AD;
++ dbg_Set_Addr_To<=23;
++ when 2 =>
++ when others =>
++ end case;
++ --}}}
+
+- 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 "00101" | "00110" | "00111" =>
++ --{{{
++ -- Zero Page
++-- if IR(7 downto 6) /= "10" and IR(1 downto 0) = "10" then--0x-7x,cx-fx, x=2,6,a,e
++ if IR(7 downto 6) /= "10" and IR(1) = '1' and (mode="00" or IR(0)='0') then--covers 0x-7x,cx-fx x=2,3,6,7,a,b,e,f, for 6502 undocs
++ -- Read-Modify-Write
++ if Mode="00" and IR(0)='1' then
++ LDA<='1';
++ end if;
++ tLCycle <= "100";
++ dbg_LCycle<=12;
++ case to_integer(unsigned(MCycle)) is
++ when 1 =>
++ Jump <= "01";
++ LDAD <= '1';
++ Set_Addr_To <= Set_Addr_To_AD;
++ dbg_Set_Addr_To<=24;
++ when 2 =>
++ LDDI <= '1';
++ if Mode="00" then--The old 6500 writes back what is just read, before changing. The 65c does another read
++ Write <= '1';
++ end if;
++ Set_Addr_To <= Set_Addr_To_AD;
++ dbg_Set_Addr_To<=25;
++ when 3 =>
++ LDALU <= '1';
++ SaveP <= '1';
++ Write <= '1';
++ Set_Addr_To <= Set_Addr_To_AD;
++ dbg_Set_Addr_To<=26;
++ when 4 =>
++ if Mode="00" and IR(0)='1' then
++ tALUmore <= '1';--ML:For undoc DCP/DCM support
++ end if;
++ when 0 =>
++ if Mode="00" and IR(0)='1' then
++ SaveP <= '1';--ML:For undoc DCP/DCM support, save again after compare
++ end if;
++ when others =>
++ end case;
++ else
++ tLCycle <= "010";
++ dbg_LCycle<=13;
++ if IR(7 downto 6) /= "10" then
++ LDA <= '1';
++ if Mode="00" and IR(1)='1' then--b3
++ LDX <= '1';--undoc, can load both A and X
++ end if;
++ 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 <= Set_Addr_To_AD;
++ dbg_Set_Addr_To<=27;
++ when 2 =>
++ when others =>
++ end case;
++ end if;
++ --}}}
+
+- when "10000" =>
+- --{{{
+- -- Relative
++ when "01100" =>
++ --{{{
++ -- Absolute
++ if IR(7 downto 6) = "01" and IR(4 downto 0) = "01100" then--4c,6c
++ -- JMP
++ if IR(5) = '0' then
++ --tLCycle <= "011";
++ tLCycle <= "010";
++ dbg_LCycle<=14;
++ case to_integer(unsigned(MCycle)) is
++ when 1 =>
++ Jump <= "01";
++ LDDI <= '1';
++ when 2 =>
++ Jump <= "10"; -- DIDL
++ when others =>
++ end case;
++ else
++ --tLCycle <= "101";
++ tLCycle <= "100"; -- mikej
++ dbg_LCycle<=15;
++ case to_integer(unsigned(MCycle)) is
++ when 1 =>
++ Jump <= "01";
++ LDDI <= '1';
++ LDBAL <= '1';
++ when 2 =>
++ LDBAH <= '1';
++ if Mode /= "00" then
++ Jump <= "10"; -- DIDL
++ end if;
++ if Mode = "00" then
++ Set_Addr_To <= Set_Addr_To_BA;
++ dbg_Set_Addr_To<=28;
++ end if;
++ when 3 =>
++ LDDI <= '1';
++ if Mode = "00" then
++ Set_Addr_To <= Set_Addr_To_BA;
++ dbg_Set_Addr_To<=29;
++ BAAdd <= "01"; -- DB Inc
++ else
++ Jump <= "01";
++ end if;
++ when 4 =>
++ Jump <= "10"; -- DIDL
++ when others =>
++ end case;
++ end if;
++ else
++ tLCycle <= "011";
++ dbg_LCycle<=16;
++ case to_integer(unsigned(MCycle)) is
++ when 0 =>
++ if IR(7 downto 5) = "001" then--2c-BIT
++ SaveP <= '1';
++ end if;
++ when 1 =>
++ Jump <= "01";
++ LDBAL <= '1';
++ when 2 =>
++ Jump <= "01";
++ LDBAH <= '1';
++ if IR(7 downto 5) = "100" then--80, sty, the only write in this group
++ Write <= '1';
++ end if;
++ Set_Addr_To <= Set_Addr_To_BA;
++ dbg_Set_Addr_To<=30;
++ when 3 =>
++ when others =>
++ end case;
++ end if;
++ --}}}
+
+- -- 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
++ when "01101" | "01110" | "01111" =>
++ --{{{
++ -- Absolute
++-- if IR(7 downto 6) /= "10" and IR(1 downto 0) = "10" then--0x-7x,cx-fx, x=2,6,a,e
++ if IR(7 downto 6) /= "10" and IR(1) = '1' and (mode="00" or IR(0)='0') then--covers 0x-7x,cx-fx x=2,3,6,7,a,b,e,f, for 6502 undocs
++ -- Read-Modify-Write
++ tLCycle <= "101";
++ dbg_LCycle<=17;
++ case to_integer(unsigned(MCycle)) is
++ when 1 =>
++ Jump <= "01";
++ LDBAL <= '1';
++ when 2 =>
++ Jump <= "01";
++ LDBAH <= '1';
++ Set_Addr_To <= Set_Addr_To_BA;
++ dbg_Set_Addr_To<=31;
++ when 3 =>
++ LDDI <= '1';
++ if Mode="00" then--The old 6500 writes back what is just read, before changing. The 65c does another read
++ Write <= '1';
++ end if;
++ Set_Addr_To <= Set_Addr_To_BA;
++ dbg_Set_Addr_To<=32;
++ when 4 =>
++ Write <= '1';
++ LDALU <= '1';
++ SaveP <= '1';
++ Set_Addr_To <= Set_Addr_To_BA;
++ dbg_Set_Addr_To<=33;
++ when 5 =>
++ --SaveP <= '0'; -- MIKEJ was 1
++ if Mode="00" and IR(0)='1' then
++ tALUmore <= '1';--ML:For undoc DCP/DCM support
++ end if;
++ when 0 =>
++ if Mode="00" and IR(0)='1' then
++ SaveP <= '1';--ML:For undoc DCP/DCM support, save again after compare
++ end if;
++ when others =>
++ end case;
++ else
++ tLCycle <= "011";
++ dbg_LCycle<=18;
++ if IR(7 downto 6) /= "10" then
++ LDA <= '1';
++ if Mode="00" and IR(1)='1' then--b3
++ LDX <= '1';--undoc, can load both A and X
++ end if;
++ 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 <= Set_Addr_To_BA;
++ dbg_Set_Addr_To<=34;
++ when 3 =>
++ when others =>
++ end case;
++ end if;
++ --}}}
+
+- LCycle <= "011"; -- We're done @ T3 if branching...upper
+- -- level logic will stop at T2 if no page cross
+- -- (See the Break signal)
+- else
++ when "10000" =>
++ --{{{
++ -- Relative
+
+- LCycle <= "001";
++ -- 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
++ tLCycle <= "011"; -- We're done @ T3 if branching...upper
++ -- level logic will stop at T2 if no page cross
++ -- (See the Break signal)
++ dbg_LCycle<=19;
++ else
++ tLCycle <= "001";
++ dbg_LCycle<=20;
+
+- end if;
++ end if;
+
+- -- This decodes the current microcycle and takes the
+- -- proper course of action...
+- case to_integer(unsigned(MCycle)) is
++ -- 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 =>
++ -- 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.
++ 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.
++ 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 =>
++ -- 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.
++ 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.
++ 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 =>
++ -- 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.
++ when others => null; -- Do nothing.
+
+- end case;
+- --}}}
++ 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 "10001" | "10011" =>
++ --{{{
++ -- Zero Page Indirect Indexed (d),y
++ tLCycle <= "101";
++ dbg_LCycle<=21;
++ if IR(7 downto 6) /= "10" then--91,b1,93,b3 only
++ LDA <= '1';
++ if Mode="00" and IR(1)='1' then--b3
++ LDX <= '1';--undoc, can load both A and X
++ end if;
++ end if;
++ case to_integer(unsigned(MCycle)) is
++ when 1 =>
++ Jump <= "01";
++ LDAD <= '1';
++ Set_Addr_To <= Set_Addr_To_AD;
++ dbg_Set_Addr_To<=35;
++ when 2 =>
++ LDBAL <= '1';
++ BAAdd <= "01"; -- DB Inc
++ Set_Addr_To <= Set_Addr_To_AD;
++ dbg_Set_Addr_To<=36;
++ when 3 =>
++ Set_BusA_To <= Set_BusA_To_Y;
++ dbg_Set_BusA_To<=18;
++ BAAdd <= "10"; -- BA Add
++ LDBAH <= '1';
++ Set_Addr_To <= Set_Addr_To_BA;
++ dbg_Set_Addr_To<=37;
++ when 4 =>
++ BAAdd <= "11"; -- BA Adj
++ if IR(7 downto 5) = "100" or IR(1)='1' then
++ Write <= '1';
++ else
++ BreakAtNA <= '1';
++ if Mode="00" and IR(1)='1' then
++ tALUmore <= '1';--ML:For undoc
++ end if;
++ end if;
++ Set_Addr_To <= Set_Addr_To_BA;
++ dbg_Set_Addr_To<=38;
++ when 5 =>
++ if Mode="00" and IR(1)='1' then
++ tALUmore <= '1';--ML:For undoc
++ end if;
++ when 0 =>
++ if Mode="00" and IR(1)='1' then
++ SaveP <= '1';--ML:For undoc
++ end if;
++ 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;
++ when "10100" | "10101" | "10110" | "10111" =>
++ --{{{
++ -- Zero Page, X
++-- if IR(7 downto 6) /= "10" and IR(1 downto 0) = "10" then--16,36,56,76,d6,f6
++ if IR(7 downto 6) /= "10" and IR(1) = '1' and (Mode="00" or IR(0)='0') then--covers 0x-7x,cx-fx x=2,3,6,7,a,b,e,f, for 6502 undocs
++ -- Read-Modify-Write
++ if Mode="00" and IR(0)='1' then
++ LDA<='1';
++ end if;
++ tLCycle <= "101";
++ dbg_LCycle<=22;
++ case to_integer(unsigned(MCycle)) is
++ when 1 =>
++ Jump <= "01";
++ LDAD <= '1';
++ Set_Addr_To <= Set_Addr_To_AD;
++ dbg_Set_Addr_To<=39;
++ when 2 =>
++ ADAdd <= '1';
++ Set_Addr_To <= Set_Addr_To_AD;
++ dbg_Set_Addr_To<=40;
++ when 3 =>
++ LDDI <= '1';
++ if Mode="00" then--The old 6500 writes back what is just read, before changing. The 65c does another read
++ Write <= '1';
++ end if;
++ Set_Addr_To <= Set_Addr_To_AD;
++ dbg_Set_Addr_To<=41;
++ when 4 =>
++ LDALU <= '1';
++ SaveP <= '1';
++ Write <= '1';
++ Set_Addr_To <= Set_Addr_To_AD;
++ dbg_Set_Addr_To<=42;
++ when 5 =>
++ if Mode="00" and IR(0)='1' then
++ tALUmore <= '1';--ML:For undoc DCP/DCM support
++ end if;
++ when 0 =>
++ if Mode="00" and IR(0)='1' then
++ SaveP <= '1';--ML:For undoc DCP/DCM support, save again after compare
++ end if;
++ when others =>
++ end case;
++ elsif Mode="00" and IR(7 downto 6)/="10" and IR(4)='1' and IR(1 downto 0)="00" then --covers 1x,3x,5x,7x,dx,fx, for skb/nopzx 6502 undocs
++ tLCycle <= "011";--SKB's at x4
++ dbg_LCycle<=222;
++ case to_integer(unsigned(MCycle)) is
++ when 1 =>
++ Jump <= "01";--skip a byte
++ when others=>
++ end case;
++ else
++ tLCycle <= "011";
++ dbg_LCycle<=23;
++ if IR(7 downto 6) /= "10" then
++ LDA <= '1';
++ if Mode="00" and IR(1 downto 0)="11" then--x7
++ LDX <= '1';--undoc, can load both A and X
++ end if;
++ end if;
++ case to_integer(unsigned(MCycle)) is
++ when 0 =>
++ when 1 =>
++ Jump <= "01";
++ LDAD <= '1';
++ Set_Addr_To <= Set_Addr_To_AD;
++ dbg_Set_Addr_To<=43;
++ when 2 =>
++ ADAdd <= '1';
++ -- Added this check for Y reg. use...
++ if (IR(3 downto 0) = "0110") then--96,b6
++ 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;
+- --}}}
++ if IR(7 downto 5) = "100" then--94,95,96,97 the only write instruction
++ Write <= '1';
++ end if;
++ Set_Addr_To <= Set_Addr_To_AD;
++ dbg_Set_Addr_To<=44;
++ 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 "11001" | "11011" =>
++ --{{{
++ -- Absolute Y
++ tLCycle <= "100";
++ dbg_LCycle<=24;
++ if IR(7 downto 6) /= "10" then
++ LDA <= '1';
++ if Mode="00" and IR(1 downto 0)="11" then--xb
++ LDX <= '1';--undoc, can load both A and X
++ end if;
++ end if;
++ case to_integer(unsigned(MCycle)) is
++ when 1 =>
++ Jump <= "01";
++ LDBAL <= '1';
++ when 2 =>
++ Jump <= "01";
++ Set_BusA_To <= Set_BusA_To_Y;
++ dbg_Set_BusA_To<=19;
++ BAAdd <= "10"; -- BA Add
++ LDBAH <= '1';
++ Set_Addr_To <= Set_Addr_To_BA;
++ dbg_Set_Addr_To<=45;
++ when 3 =>
++ BAAdd <= "11"; -- BA adj
++-- if IR(7 downto 5) = "100" then--99/9b
++ if IR(7 downto 5) = "100" or IR(1)='1' then
++ Write <= '1';
++ else
++ BreakAtNA <= '1';
++ end if;
++ Set_Addr_To <= Set_Addr_To_BA;
++ dbg_Set_Addr_To<=46;
++ when 4 =>
++ if Mode="00" and IR(1)='1' then
++ tALUmore <= '1';--ML:For undoc
++ end if;
++ when 0 =>
++ if Mode="00" and IR(1)='1' then
++ SaveP <= '1';--ML:For undoc
++ end if;
++ when others =>
++ end case;
++ --}}}
+
+- when "11100" | "11101" | "11110" | "11111" =>
+- --{{{
+- -- Absolute X
++ 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;
++-- if IR(7 downto 6) /= "10" and IR(1 downto 0) = "10" then--1x,3x,5x,7x,dx,fx, x=c,d,e,f
++ if IR(7 downto 6) /= "10" and IR(1) = '1' and (Mode="00" or IR(0)='0') then--covers 0x-7x,cx-fx x=2,3,6,7,a,b,e,f, for 6502 undocs
++ -- Read-Modify-Write
++ tLCycle <= "110";
++ dbg_LCycle<=25;
++ case to_integer(unsigned(MCycle)) is
++ when 1 =>
++ Jump <= "01";
++ LDBAL <= '1';
++ when 2 =>
++ Jump <= "01";
++ Set_BusA_To <= Set_BusA_To_X;
++ dbg_Set_BusA_To<=20;
++ BAAdd <= "10"; -- BA Add
++ LDBAH <= '1';
++ Set_Addr_To <= Set_Addr_To_BA;
++ dbg_Set_Addr_To<=47;
++ when 3 =>
++ BAAdd <= "11"; -- BA adj
++ Set_Addr_To <= Set_Addr_To_BA;
++ dbg_Set_Addr_To<=48;
++ when 4 =>
++ LDDI <= '1';
++ if Mode="00" then--The old 6500 writes back what is just read, before changing. The 65c does another read
++ Write <= '1';
++ end if;
++ Set_Addr_To <= Set_Addr_To_BA;
++ dbg_Set_Addr_To<=49;
++ when 5 =>
++ LDALU <= '1';
++ SaveP <= '1';
++ Write <= '1';
++ Set_Addr_To <= Set_Addr_To_BA;
++ dbg_Set_Addr_To<=50;
++ when 6 =>
++ if Mode="00" and IR(0)='1' then
++ tALUmore <= '1';--ML:For undoc DCP/DCM support
++ end if;
++ when 0 =>
++ if Mode="00" and IR(0)='1' then
++ SaveP <= '1';--ML:For undoc DCP/DCM support, save again after compare
++ end if;
++ when others =>
++ end case;
++-- elsif Mode="00" and IR(7 downto 6)/="10" and IR(4)='1' and IR(1 downto 0)="00" then --covers 1x,3x,5x,7x,dx,fx, for 6502 skw/nopax undocs
++-- tLCycle <= "100";--SKW's at xc
++-- dbg_LCycle<=260;
++-- case to_integer(unsigned(MCycle)) is
++-- when 1 =>
++-- Jump <= "01";--skip a byte
++-- when 2 =>
++-- Jump <= "01";--skip a byte
++-- when 3 =>
++-- BreakAtNA <= '1';
++-- when others=>
++-- end case;
++ else--9c,9d,9e,9f,bc,bd,be,bf
++ tLCycle <= "100";
++ dbg_LCycle<=26;
++ if IR(7 downto 6) /= "10" then
++ if Mode/="00" or IR(4)='0' or IR(1 downto 0)/="00" then --covers 1x,3x,5x,7x,dx,fx, for 6502 skw/nopax undocs
++ LDA <= '1';
++ if Mode="00" and IR(1 downto 0)="11" then--9f,bf
++ LDX <= '1';--undoc, can load both A and X
++ end if;
++ end if;
++ 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!! (added undoc 9e,9f,bf)
++-- if (IR = "10-1111-") then
++ if(IR(7 downto 6)="10" and IR(4 downto 1)="1111") then
++ Set_BusA_To <= Set_BusA_To_Y;
++ dbg_Set_BusA_To<=21;
++ else
++ Set_BusA_To <= Set_BusA_To_X;
++ dbg_Set_BusA_To<=22;
++ end if;
++ BAAdd <= "10"; -- BA Add
++ LDBAH <= '1';
++ Set_Addr_To <= Set_Addr_To_BA;
++ dbg_Set_Addr_To<=51;
++ when 3 =>
++ BAAdd <= "11"; -- BA adj
++ if IR(7 downto 5) = "100" then--9x
++ Write <= '1';
++ else
++ BreakAtNA <= '1';
++ end if;
++ Set_Addr_To <= Set_Addr_To_BA;
++ dbg_Set_Addr_To<=52;
++ 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;
++ process (IR, MCycle, Mode,tALUmore)
++ 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" =>-- "---0 xx00", xx!="10"
++ case IR(7 downto 5) is
++ when "110" | "111" =>--c0,c4,cc,e0,e5,ec
++ -- CP
++ ALU_Op <= ALU_OP_CMP;
++ when "101" =>--a0,a4,ac
++ -- LD
++ ALU_Op <= ALU_OP_EQ2;
++ when "001" =>--20,24,2c (20 is ignored, as its a jmp)
++ -- BIT
++ ALU_Op <= ALU_OP_BIT;
++ when others =>--other x0,x4,xc
++ -- NOP/ST
++ ALU_Op <= ALU_OP_EQ1;
++ end case;
++ when "010" =>-- "---0 1000"
++ case IR(7 downto 5) is
++ when "111" | "110" =>--c8,e8
++ -- IN
++ ALU_Op <= ALU_OP_INC;
++ when "100" =>--88
++ -- DEY
++ ALU_Op <= ALU_OP_DEC;
++ when others =>
++ -- LD
++ ALU_Op <= ALU_OP_EQ3;
++ end case;
++ when "110" =>-- "---1 1000"
++ case IR(7 downto 5) is
++ when "100" =>--98
++ -- TYA
++ ALU_Op <= ALU_OP_EQ3;
++ when others =>
++ ALU_Op <= ALU_OP_UNDEF;
++ end case;
++ when others =>-- "---x xx00"
++ case IR(7 downto 5) is
++ when "101" =>--ax,bx
++ -- LD
++ ALU_Op <= ALU_OP_EQ3;
++ when others =>
++ ALU_Op <= ALU_OP_EQ1;
++ end case;
++ end case;
++ --}}}
++ when "01" => -- OR
++ --{{{
++ case(to_integer(unsigned(IR(7 downto 5)))) is
++ when 0=>
++ ALU_Op<=ALU_OP_OR;
++ when 1=>
++ ALU_Op<=ALU_OP_AND;
++ when 2=>
++ ALU_Op<=ALU_OP_EOR;
++ when 3=>
++ ALU_Op<=ALU_OP_ADC;
++ when 4=>
++ ALU_Op<=ALU_OP_EQ1;--sta
++ when 5=>
++ ALU_Op<=ALU_OP_EQ2;--lda
++ when 6=>
++ ALU_Op<=ALU_OP_CMP;
++ when others=>
++ ALU_Op<=ALU_OP_SBC;
++ end case;
++--ML:replaced by above case()
++-- ALU_Op(3) <= '0';
++-- ALU_Op(2 downto 0) <= IR(7 downto 5);
++ --}}}
++ when "10" =>
++ --{{{
++ case(to_integer(unsigned(IR(7 downto 5)))) is
++ when 0=>
++ ALU_Op<=ALU_OP_ASL;
++ when 1=>
++ ALU_Op<=ALU_OP_ROL;
++ when 2=>
++ ALU_Op<=ALU_OP_LSR;
++ when 3=>
++ ALU_Op<=ALU_OP_ROR;
++ when 4=>
++ ALU_Op<=ALU_OP_BIT;
++ when 5=>
++ ALU_Op<=ALU_OP_EQ3;--ldx
++ when 6=>
++ ALU_Op<=ALU_OP_DEC;
++ when others=>
++ ALU_Op<=ALU_OP_INC;
++ end case;
++--ML:replaced by above case()
++-- 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" and Mode/="00" then--ML:00011010,1a->inc acc, not on 6502
++ -- INC
++ ALU_Op <= ALU_OP_INC;
++ end if;
++ when "001" =>
++ if IR(4 downto 2) = "110" and Mode/="00" then--ML:00111010,3a->dec acc, not on 6502
++ -- DEC
++ ALU_Op <= ALU_OP_DEC;
++ end if;
++ when "100" =>
++ if IR(4 downto 2) = "010" then --10001010,8a->TXA
++ -- TXA
++ ALU_Op <= ALU_OP_EQ2;
++ else --100xxx10, 82,86,8e,92,96,9a,9e
++ ALU_Op <= ALU_OP_EQ1;
++ end if;
++ when others =>
++ end case;
++ --}}}
++ when others =>--"11" undoc double alu ops
++ --{{{
++ case IR(7 downto 5) is
++ when "101" =>--ax,bx
++ ALU_Op <= ALU_OP_EQ1;
++ when others =>
++-- if MCycle >= tLCycle then
++ if tALUmore='1' then
++ case(to_integer(unsigned(IR(7 downto 5)))) is
++ when 0=>
++ ALU_Op<=ALU_OP_OR;
++ when 1=>
++ ALU_Op<=ALU_OP_AND;
++ when 2=>
++ ALU_Op<=ALU_OP_EOR;
++ when 3=>
++ ALU_Op<=ALU_OP_ADC;
++ when 4=>
++ ALU_Op<=ALU_OP_EQ1;--sta
++ when 5=>
++ ALU_Op<=ALU_OP_EQ2;--lda
++ when 6=>
++ ALU_Op<=ALU_OP_CMP;
++ when others=>
++ ALU_Op<=ALU_OP_SBC;
++ end case;
++--replaced by above case()
++-- ALU_Op(3) <= '0';
++-- ALU_Op(2 downto 0) <= IR(7 downto 5);
++ else
++ case(to_integer(unsigned(IR(7 downto 5)))) is
++ when 0=>
++ ALU_Op<=ALU_OP_ASL;
++ when 1=>
++ ALU_Op<=ALU_OP_ROL;
++ when 2=>
++ ALU_Op<=ALU_OP_LSR;
++ when 3=>
++ ALU_Op<=ALU_OP_ROR;
++ when 4=>
++ ALU_Op<=ALU_OP_BIT;
++ when 5=>
++ ALU_Op<=ALU_OP_EQ3;--ldx
++ when 6=>
++ ALU_Op<=ALU_OP_DEC;
++ when others=>
++ ALU_Op<=ALU_OP_INC;
++ end case;
++--replaced by above case()
++-- ALU_Op(3) <= '1';
++-- ALU_Op(2 downto 0) <= IR(7 downto 5);
++ end if;
++ end case;
++ --}}}
++ end case;
++ end process;
+
+ end;
+diff --git a/T65/T65_Pack.vhd b/T65/T65_Pack.vhd
+index e025e1b..1c9178d 100644
+--- a/T65/T65_Pack.vhd
++++ b/T65/T65_Pack.vhd
+@@ -2,6 +2,8 @@
+ -- T65(b) core. In an effort to merge and maintain bug fixes ....
+ --
+ --
++-- Ver 303 ost(ML) July 2014
++-- "magic" constants converted to vhdl types
+ -- Ver 300 Bugfixes by ehenciak added
+ -- MikeJ March 2005
+ -- Latest version from www.fpgaarcade.com (original www.opencores.org)
+@@ -59,59 +61,110 @@ 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;
++ 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_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;
+- AddY : 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;
++ type T_Set_BusA_To is
++ (
++ Set_BusA_To_DI,
++ Set_BusA_To_ABC,
++ Set_BusA_To_X,
++ Set_BusA_To_Y,
++ Set_BusA_To_S,
++ Set_BusA_To_P,
++ Set_BusA_To_DONTCARE
++ );
++ type T_Set_Addr_To is
++ (
++ Set_Addr_To_S,
++ Set_Addr_To_AD,
++ Set_Addr_To_PBR,
++ Set_Addr_To_BA
++ );
++ type T_Write_Data is
++ (
++ Write_Data_DL,
++ Write_Data_ABC,
++ Write_Data_X,
++ Write_Data_Y,
++ Write_Data_S,
++ Write_Data_P,
++ Write_Data_PCL,
++ Write_Data_PCH,
++ Write_Data_DONTCARE
++ );
++ type T_ALU_OP is
++ (
++ ALU_OP_OR, --"0000"
++ ALU_OP_AND, --"0001"
++ ALU_OP_EOR, --"0010"
++ ALU_OP_ADC, --"0011"
++ ALU_OP_EQ1, --"0100" EQ1 does not change N,Z flags, EQ2/3 does.
++ ALU_OP_EQ2, --"0101"Not sure yet whats the difference between EQ2&3. They seem to do the same ALU op
++ ALU_OP_CMP, --"0110"
++ ALU_OP_SBC, --"0111"
++ ALU_OP_ASL, --"1000"
++ ALU_OP_ROL, --"1001"
++ ALU_OP_LSR, --"1010"
++ ALU_OP_ROR, --"1011"
++ ALU_OP_BIT, --"1100"
++ ALU_OP_EQ3, --"1101"
++ ALU_OP_DEC, --"1110"
++ ALU_OP_INC, --"1111"
++ ALU_OP_UNDEF--"----"--may be replaced with any?
++ );
+
+- 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;
++ 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 T_ALU_Op;
++ Set_BusA_To : out T_Set_BusA_To;-- DI,A,X,Y,S,P
++ Set_Addr_To : out T_Set_Addr_To;-- PC Adder,S,AD,BA
++ Write_Data : out T_Write_Data;-- 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;
++ AddY : 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;
++ ALUmore : 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 T_ALU_Op;
++ 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;