OSDN Git Service

debug update.
[motonesfpga/motonesfpga.git] / de0_cv_nes / mos6502.vhd
index cc6a641..a2e7641 100644 (file)
@@ -11,9 +11,11 @@ entity mos6502 is
             pi_rdy         : in std_logic;\r
             pi_irq_n       : in std_logic;\r
             pi_nmi_n       : in std_logic;\r
-            po_r_nw        : out std_logic;\r
+            po_oe_n        : out std_logic;\r
+            po_we_n        : out std_logic;\r
             po_addr        : out std_logic_vector ( 15 downto 0);\r
-            pio_d_io       : inout std_logic_vector ( 7 downto 0)\r
+            pio_d_io       : inout std_logic_vector ( 7 downto 0);\r
+            po_exc_cnt     : out std_logic_vector (63 downto 0)\r
     );\r
 end mos6502;\r
 \r
@@ -89,6 +91,9 @@ type cpu_main_state is (
     --reset vector.\r
     ST_RS_T0, ST_RS_T1, ST_RS_T2, ST_RS_T3, ST_RS_T4, ST_RS_T5, ST_RS_T6, ST_RS_T7,\r
 \r
+    --nmi interrupt.\r
+              ST_NM_T1, ST_NM_T2, ST_NM_T3, ST_NM_T4, ST_NM_T5, ST_NM_T6, ST_NM_T7,\r
+\r
     --invalid state\r
     ST_INV\r
     );\r
@@ -130,7 +135,7 @@ constant inst_decode_rom : cpu_state_array := (
   --48          49          4a          4b          4c          4d          4e          4f\r
     ST_A51_T1,  ST_A21_T1,  ST_A1_T1,   ST_INV,     ST_A561_T1, ST_A23_T1,  ST_A42_T1,  ST_INV,\r
   --50          51          52          53          54          55          56          57\r
-    ST_A58_T1,  ST_A27_T1,  ST_INV,     ST_INV,     ST_A26_T1,  ST_INV,     ST_A43_T1,  ST_INV,\r
+    ST_A58_T1,  ST_A27_T1,  ST_INV,     ST_INV,     ST_A26_T1,  ST_A26_T1,  ST_A43_T1,  ST_INV,\r
   --58          59          5a          5b          5c          5d          5e          5f\r
     ST_A1_T1,   ST_A25_T1,  ST_INV,     ST_INV,     ST_INV,     ST_A25_T1,  ST_A44_T1,  ST_INV,\r
   --60          61          62          63          64          65          66          67\r
@@ -138,7 +143,7 @@ constant inst_decode_rom : cpu_state_array := (
   --68          69          6a          6b          6c          6d          6e          6f\r
     ST_A52_T1,  ST_A21_T1,  ST_A1_T1,   ST_INV,     ST_A562_T1, ST_A23_T1,  ST_A42_T1,  ST_INV,\r
   --70          71          72          73          74          75          76          77\r
-    ST_A58_T1,  ST_A27_T1,  ST_INV,     ST_INV,     ST_A26_T1,  ST_INV,     ST_A43_T1,  ST_INV,\r
+    ST_A58_T1,  ST_A27_T1,  ST_INV,     ST_INV,     ST_A26_T1,  ST_A26_T1,  ST_A43_T1,  ST_INV,\r
   --78          79          7a          7b          7c          7d          7e          7f\r
     ST_A1_T1,   ST_A25_T1,  ST_INV,     ST_INV,     ST_INV,     ST_A25_T1,  ST_A44_T1,  ST_INV,\r
   --80          81          82          83          84          85          86          87\r
@@ -154,15 +159,15 @@ constant inst_decode_rom : cpu_state_array := (
   --a8          a9          aa          ab          ac          ad          ae          af\r
     ST_A1_T1,   ST_A21_T1,  ST_A1_T1,   ST_INV,     ST_A23_T1,  ST_A23_T1,  ST_A23_T1,  ST_INV,\r
   --b0          b1          b2          b3          b4          b5          b6          b7\r
-    ST_A58_T1,  ST_A27_T1,  ST_INV,     ST_A26_T1,  ST_A26_T1,  ST_A26_T1,  ST_INV,     ST_INV,\r
+    ST_A58_T1,  ST_A27_T1,  ST_INV,     ST_A26_T1,  ST_A26_T1,  ST_A26_T1,  ST_A26_T1,  ST_INV,\r
   --b8          b9          ba          bb          bc          bd          be          bf\r
     ST_A1_T1,   ST_A25_T1,  ST_A1_T1,   ST_INV,     ST_A25_T1,  ST_A25_T1,  ST_A25_T1,  ST_INV,\r
   --c0          c1          c2          c3          c4          c5          c6          c7\r
-    ST_A21_T1,  ST_A24_T1,  ST_INV,     ST_INV,     ST_INV,     ST_A22_T1,  ST_A41_T1,  ST_INV,\r
+    ST_A21_T1,  ST_A24_T1,  ST_INV,     ST_INV,     ST_A22_T1,  ST_A22_T1,  ST_A41_T1,  ST_INV,\r
   --c8          c9          ca          cb          cc          cd          ce          cf\r
     ST_A1_T1,   ST_A21_T1,  ST_A1_T1,   ST_INV,     ST_A23_T1,  ST_A23_T1,  ST_A42_T1,  ST_INV,\r
   --d0          d1          d2          d3          d4          d5          d6          d7\r
-    ST_A58_T1,  ST_A27_T1,  ST_INV,     ST_INV,     ST_A26_T1,  ST_INV,     ST_A43_T1,  ST_INV,\r
+    ST_A58_T1,  ST_A27_T1,  ST_INV,     ST_INV,     ST_A26_T1,  ST_A26_T1,  ST_A43_T1,  ST_INV,\r
   --d8          d9          da          db          dc          dd          de          df\r
     ST_A1_T1,   ST_A25_T1,  ST_INV,     ST_INV,     ST_INV,     ST_A25_T1,  ST_A44_T1,  ST_INV,\r
   --e0          e1          e2          e3          e4          e5          e6          e7\r
@@ -221,18 +226,48 @@ signal reg_tmp_h    : std_logic_vector (7 downto 0);
 signal reg_tmp_data : std_logic_vector (7 downto 0);\r
 \r
 --bus i/o reg.\r
-signal reg_r_nw     : std_logic;\r
+signal reg_oe_n     : std_logic;\r
+signal reg_we_n     : std_logic;\r
 signal reg_addr     : std_logic_vector (15 downto 0);\r
 signal reg_d_in     : std_logic_vector (7 downto 0);\r
 signal reg_d_out    : std_logic_vector (7 downto 0);\r
 \r
+signal reg_nmi_handled  : integer range 0 to 1;\r
+signal reg_dma_set      : integer range 0 to 1;\r
+\r
+--debug purpose...\r
+signal reg_exc_cnt          : std_logic_vector (63 downto 0);\r
+\r
+--constant INIT_ACC       : std_logic_vector (7 downto 0) := "00000000";\r
+--constant INIT_X         : std_logic_vector (7 downto 0) := "00000000";\r
+--constant INIT_Y         : std_logic_vector (7 downto 0) := "00000000";\r
+--constant INIT_SP        : std_logic_vector (7 downto 0) := "00000000";\r
+--constant INIT_STATUS    : std_logic_vector (7 downto 0) := "00100000";\r
+--constant INIT_PCL       : std_logic_vector (7 downto 0) := "00000000";\r
+--constant INIT_PCH       : std_logic_vector (7 downto 0) := "00000000";\r
+\r
+constant INIT_ACC       : std_logic_vector (7 downto 0) := conv_std_logic_vector(16#95#, 8);\r
+constant INIT_X         : std_logic_vector (7 downto 0) := conv_std_logic_vector(16#0d#, 8);\r
+constant INIT_Y         : std_logic_vector (7 downto 0) := conv_std_logic_vector(16#1d#, 8);\r
+constant INIT_SP        : std_logic_vector (7 downto 0) := conv_std_logic_vector(16#fc#, 8);\r
+constant INIT_STATUS    : std_logic_vector (7 downto 0) := conv_std_logic_vector(16#a5#, 8);\r
+constant INIT_PCL       : std_logic_vector (7 downto 0) := conv_std_logic_vector(16#82#, 8);\r
+constant INIT_PCH       : std_logic_vector (7 downto 0) := conv_std_logic_vector(16#80#, 8);\r
+constant INIT_EXC_CNT   : std_logic_vector (63 downto 0) := conv_std_logic_vector(16#02bd#, 16) & conv_std_logic_vector(0, 48);\r
+\r
+constant DEBUG_SW       : integer := 0;\r
 \r
 begin\r
     --state transition process...\r
     set_stat_p : process (pi_rst_n, pi_base_clk)\r
     begin\r
         if (pi_rst_n = '0') then\r
-            reg_main_state <= ST_IDLE;\r
+            if (DEBUG_SW = 0) then\r
+                reg_main_state <= ST_RS_T0;\r
+            else\r
+                --for test....\r
+                reg_main_state <= ST_CM_T0;\r
+            end if;\r
             reg_sub_state <= ST_SUB00;\r
         elsif (rising_edge(pi_base_clk)) then\r
             reg_main_state <= reg_main_next_state;\r
@@ -317,21 +352,35 @@ begin
 \r
     --state change to next.\r
     tx_next_main_stat_p : process (pi_rst_n, reg_main_state, reg_sub_state,\r
-                                   reg_inst, reg_tmp_condition, reg_tmp_pg_crossed)\r
+                                   reg_inst, reg_tmp_condition, reg_tmp_pg_crossed,\r
+                                   pi_nmi_n, reg_nmi_handled, reg_dma_set, pi_rdy)\r
 \r
     begin\r
         case reg_main_state is\r
             -----idle...\r
             when ST_IDLE =>\r
                 if (pi_rst_n = '0') then\r
-                    reg_main_next_state <= reg_main_state;\r
+                    if (DEBUG_SW = 0) then\r
+                        reg_main_next_state <= ST_RS_T0;\r
+                    else\r
+                        --for test....\r
+                        reg_main_next_state <= ST_CM_T0;\r
+                    end if;\r
+                elsif (reg_sub_state = ST_SUB73 and reg_dma_set = 1 and pi_rdy = '1') then\r
+                    --ST_CM_T0 is canceled when dma initiated.\r
+                    --redo ST_CM_T0.\r
+                    reg_main_next_state <= ST_CM_T0;\r
                 else\r
-                    reg_main_next_state <= ST_RS_T0;\r
+                    reg_main_next_state <= reg_main_state;\r
                 end if;\r
             -----reset...\r
             when ST_RS_T0 =>\r
                 if (reg_sub_state = ST_SUB73) then\r
-                    reg_main_next_state <= ST_RS_T1;\r
+                    if (pi_rst_n = '0') then\r
+                        reg_main_next_state <= reg_main_state;\r
+                    else\r
+                        reg_main_next_state <= ST_RS_T1;\r
+                    end if;\r
                 else\r
                     reg_main_next_state <= reg_main_state;\r
                 end if;\r
@@ -381,8 +430,17 @@ begin
             --instruction fetch\r
             when ST_CM_T0 =>\r
                 if (reg_sub_state = ST_SUB73) then\r
-                    ---instruction decode next state.\r
-                    reg_main_next_state <= inst_decode_rom(conv_integer(reg_inst));\r
+                    if (pi_nmi_n = '0' and reg_nmi_handled = 0) then\r
+                        --nmi raised. transit to nmi state.\r
+                        reg_main_next_state <= ST_NM_T1;\r
+                    elsif (pi_rdy = '0') then\r
+                        --dma started.\r
+                        reg_main_next_state <= ST_IDLE;\r
+                    else\r
+                        ---instruction decode next state.\r
+                        ---pc inc is executed at the end of the cycle (ST_SUB73).\r
+                        reg_main_next_state <= inst_decode_rom(conv_integer(reg_inst));\r
+                    end if;\r
                 else\r
                     reg_main_next_state <= reg_main_state;\r
                 end if;\r
@@ -743,7 +801,7 @@ begin
                 end if;\r
             when ST_A43_T2 =>\r
                 if (reg_sub_state = ST_SUB73) then\r
-                    reg_main_next_state <= ST_CM_T0;\r
+                    reg_main_next_state <= ST_A43_T3;\r
                 else\r
                     reg_main_next_state <= reg_main_state;\r
                 end if;\r
@@ -976,7 +1034,7 @@ begin
                 if (reg_sub_state = ST_SUB73) then\r
                     if (reg_tmp_pg_crossed = '1') then\r
                         --page crossed. move to next.\r
-                        reg_main_next_state <= ST_A58_T2;\r
+                        reg_main_next_state <= ST_A58_T3;\r
                     else\r
                         --page not crossed. move to next inst fetch.\r
                         reg_main_next_state <= ST_CM_T0;\r
@@ -991,17 +1049,63 @@ begin
                     reg_main_next_state <= reg_main_state;\r
                 end if;\r
 \r
+            -----nmi...\r
+            when ST_NM_T1 =>\r
+                if (reg_sub_state = ST_SUB73) then\r
+                    reg_main_next_state <= ST_NM_T2;\r
+                else\r
+                    reg_main_next_state <= reg_main_state;\r
+                end if;\r
+            when ST_NM_T2 =>\r
+                if (reg_sub_state = ST_SUB73) then\r
+                    reg_main_next_state <= ST_NM_T3;\r
+                else\r
+                    reg_main_next_state <= reg_main_state;\r
+                end if;\r
+            when ST_NM_T3 =>\r
+                if (reg_sub_state = ST_SUB73) then\r
+                    reg_main_next_state <= ST_NM_T4;\r
+                else\r
+                    reg_main_next_state <= reg_main_state;\r
+                end if;\r
+            when ST_NM_T4 =>\r
+                if (reg_sub_state = ST_SUB73) then\r
+                    reg_main_next_state <= ST_NM_T5;\r
+                else\r
+                    reg_main_next_state <= reg_main_state;\r
+                end if;\r
+            when ST_NM_T5 =>\r
+                if (reg_sub_state = ST_SUB73) then\r
+                    reg_main_next_state <= ST_NM_T6;\r
+                else\r
+                    reg_main_next_state <= reg_main_state;\r
+                end if;\r
+            when ST_NM_T6 =>\r
+                if (reg_sub_state = ST_SUB73) then\r
+                    reg_main_next_state <= ST_NM_T7;\r
+                else\r
+                    reg_main_next_state <= reg_main_state;\r
+                end if;\r
+            when ST_NM_T7 =>\r
+                if (reg_sub_state = ST_SUB73) then\r
+                    reg_main_next_state <= ST_CM_T0;\r
+                else\r
+                    reg_main_next_state <= reg_main_state;\r
+                end if;\r
+\r
+            --invalid state\r
             when ST_INV =>\r
                 ---failed to decode next...\r
                     reg_main_next_state <= reg_main_state;\r
---            ---not ready yet...\r
+\r
 --            when others =>\r
 --                reg_main_next_state <= reg_main_state;\r
         end case;\r
     end process;\r
 \r
 \r
-    po_r_nw     <= reg_r_nw;\r
+    po_oe_n     <= reg_oe_n;\r
+    po_we_n     <= reg_we_n;\r
     po_addr     <= reg_addr;\r
     pio_d_io    <= reg_d_out;\r
 \r
@@ -1023,15 +1127,30 @@ begin
     end if;\r
 end;\r
 \r
+procedure write_enable is\r
+begin\r
+    reg_oe_n    <= '1';\r
+    if (reg_sub_state = ST_SUB32 or\r
+        reg_sub_state = ST_SUB33 or\r
+        reg_sub_state = ST_SUB40 or\r
+        reg_sub_state = ST_SUB41\r
+        ) then\r
+        reg_we_n    <= '0';\r
+    else\r
+        reg_we_n    <= '1';\r
+    end if;\r
+end;\r
+\r
     begin\r
         if (pi_rst_n = '0') then\r
-            reg_pc_l    <= (others => '0');\r
-            reg_pc_h    <= (others => '0');\r
+            reg_pc_l    <= INIT_PCL;\r
+            reg_pc_h    <= INIT_PCH;\r
             reg_inst    <= (others => '0');\r
             reg_addr    <= (others => 'Z');\r
             reg_d_out   <= (others => 'Z');\r
             reg_d_in    <= (others => '0');\r
-            reg_r_nw    <= 'Z';\r
+            reg_oe_n    <= 'Z';\r
+            reg_we_n    <= 'Z';\r
             reg_tmp_pg_crossed  <= '0';\r
             calc_adl    := (others => '0');\r
         elsif (rising_edge(pi_base_clk)) then\r
@@ -1039,58 +1158,75 @@ end;
             --general input data register.\r
             reg_d_in    <= pio_d_io;\r
             \r
-            --i/o data bus state change.\r
+            --reset vector\r
             if (reg_main_state = ST_RS_T0) then\r
                 reg_pc_l    <= (others => '0');\r
                 reg_pc_h    <= (others => '0');\r
                 reg_inst    <= (others => '0');\r
                 reg_addr    <= (others => '0');\r
                 reg_d_out   <= (others => 'Z');\r
-                reg_r_nw    <= '1';\r
+                reg_oe_n    <= '1';\r
+                reg_we_n    <= '1';\r
             elsif (reg_main_state = ST_RS_T3) then\r
                 --dummy sp out 1.\r
-                reg_addr    <= "11111111" & reg_sp;\r
-                reg_d_out   <= (others => 'Z');\r
-                reg_r_nw    <= '0';\r
+                reg_addr    <= "00000001" & reg_sp;\r
+                reg_d_out   <= (others => '0');\r
+                write_enable;\r
             elsif (reg_main_state = ST_RS_T4) then\r
                 --dummy sp out 2.\r
-                reg_addr    <= "11111111" & (reg_sp - 1);\r
-                reg_d_out   <= (others => 'Z');\r
-                reg_r_nw    <= '0';\r
+                reg_addr    <= "00000001" & (reg_sp - 1);\r
+                reg_d_out   <= (others => '0');\r
+                write_enable;\r
             elsif (reg_main_state = ST_RS_T5) then\r
                 --dummy sp out 3.\r
-                reg_addr    <= "11111111" & (reg_sp - 2);\r
-                reg_d_out   <= (others => 'Z');\r
-                reg_r_nw    <= '0';\r
+                reg_addr    <= "00000001" & (reg_sp - 2);\r
+                reg_d_out   <= (others => '0');\r
+                write_enable;\r
             elsif (reg_main_state = ST_RS_T6) then\r
                 --reset vector low...\r
                 reg_addr    <= "1111111111111100";\r
                 reg_d_out   <= (others => 'Z');\r
-                reg_r_nw    <= '1';\r
+                reg_oe_n    <= '0';\r
+                reg_we_n    <= '1';\r
                 reg_pc_l    <= reg_d_in;\r
             elsif (reg_main_state = ST_RS_T7) then\r
                 --reset vector high...\r
                 reg_addr    <= "1111111111111101";\r
-                reg_d_out   <= (others => 'Z');\r
-                reg_r_nw    <= '1';\r
                 reg_pc_h    <= reg_d_in;\r
+\r
+            --common entry cycle.\r
             elsif (reg_main_state = ST_CM_T0) then\r
-                --init pg crossing flag.\r
+                --init flags.\r
                 reg_tmp_pg_crossed <= '0';\r
                 calc_adl    := (others => '0');\r
+                reg_d_out   <= (others => 'Z');\r
 \r
-                if (reg_sub_state = ST_SUB00) then\r
-                    --fetch next.\r
-                    reg_addr    <= reg_pc_h & reg_pc_l;\r
-                    reg_d_out   <= (others => 'Z');\r
-                    reg_r_nw    <= '1';\r
-                elsif (reg_sub_state = ST_SUB30) then\r
-                    --update instruction register.\r
-                    reg_inst    <= reg_d_in;\r
-                elsif (reg_sub_state = ST_SUB70) then\r
-                    --pc move next.\r
-                    pc_inc;\r
+                if (pi_nmi_n = '0' and reg_nmi_handled = 0) then\r
+                    --nmi raised cycle.\r
+                    reg_oe_n    <= '1';\r
+                    reg_we_n    <= '1';\r
+                    reg_addr    <= (others => 'Z');\r
+                elsif (pi_rdy = '0') then\r
+                    --dma started cycle.\r
+                    reg_oe_n    <= 'Z';\r
+                    reg_we_n    <= 'Z';\r
+                    reg_addr    <= (others => 'Z');\r
+                else\r
+                    --normal cycle.\r
+                    reg_oe_n    <= '0';\r
+                    reg_we_n    <= '1';\r
+                    if (reg_sub_state = ST_SUB00) then\r
+                        --fetch next.\r
+                        reg_addr    <= reg_pc_h & reg_pc_l;\r
+                    elsif (reg_sub_state = ST_SUB30) then\r
+                        --update instruction register.\r
+                        reg_inst    <= reg_d_in;\r
+                    elsif (reg_sub_state = ST_SUB73) then\r
+                        --pc move next.\r
+                        pc_inc;\r
+                    end if;\r
                 end if;\r
+\r
             --fetch and move next case.\r
             elsif (reg_main_state = ST_A21_T1 or\r
                 reg_main_state = ST_A22_T1 or\r
@@ -1116,6 +1252,7 @@ end;
                 reg_main_state = ST_A44_T1 or\r
                 reg_main_state = ST_A44_T2 or\r
                 reg_main_state = ST_A53_T1 or\r
+                reg_main_state = ST_A55_T1 or\r
                 reg_main_state = ST_A561_T1 or\r
                 reg_main_state = ST_A562_T1 or\r
                 reg_main_state = ST_A562_T2 or\r
@@ -1124,8 +1261,6 @@ end;
                 if (reg_sub_state = ST_SUB00) then\r
                     --fetch next.\r
                     reg_addr    <= reg_pc_h & reg_pc_l;\r
-                    reg_d_out   <= (others => 'Z');\r
-                    reg_r_nw    <= '1';\r
                 elsif (reg_sub_state = ST_SUB70) then\r
                     --pc move next.\r
                     pc_inc;\r
@@ -1146,45 +1281,33 @@ end;
                 --ind, y\r
                 --ial cycle.\r
                 reg_addr    <= "00000000" & reg_idl_l;\r
-                reg_d_out   <= (others => 'Z');\r
-                reg_r_nw    <= '1';\r
             elsif (reg_main_state = ST_A24_T3 or\r
                 reg_main_state = ST_A33_T3\r
                 ) then\r
                 --ind, x\r
                 --bal + x cycle.\r
                 reg_addr    <= "00000000" & (reg_idl_l + reg_x);\r
-                reg_d_out   <= (others => 'Z');\r
-                reg_r_nw    <= '1';\r
             elsif (reg_main_state = ST_A24_T4 or\r
                 reg_main_state = ST_A33_T4) then\r
                 --ind, x\r
                 --bal + x + 1 cycle.\r
                 reg_addr    <= "00000000" & (reg_idl_l + reg_x + 1);\r
-                reg_d_out   <= (others => 'Z');\r
-                reg_r_nw    <= '1';\r
             elsif (reg_main_state = ST_A25_T3 or\r
                 reg_main_state = ST_A34_T3 or\r
                 reg_main_state = ST_A44_T3\r
                 ) then\r
                 --abs xy\r
                 --(discarded cycle for store inst..)\r
-                if (reg_inst(1 downto 0) = "01") then\r
-                    if (reg_inst(4 downto 2) = "110") then\r
-                        --abs y\r
-                        reg_addr    <= reg_idl_h & (reg_idl_l + reg_y);\r
-                    elsif (reg_inst(4 downto 2) = "111") then\r
-                        --abs x\r
-                        reg_addr    <= reg_idl_h & (reg_idl_l + reg_x);\r
-                    end if; \r
-                elsif (reg_inst = conv_std_logic_vector(16#be#, 8)) then\r
+                if (reg_inst = conv_std_logic_vector(16#be#, 8)) then\r
                     --abs y\r
                     --ldx\r
                     reg_addr    <= reg_idl_h & (reg_idl_l + reg_y);\r
+                    calc_adl    := ("0" & reg_idl_l) + ("0" & reg_y);\r
                 elsif (reg_inst = conv_std_logic_vector(16#bc#, 8)) then\r
                     --abs x\r
                     --ldy\r
                     reg_addr    <= reg_idl_h & (reg_idl_l + reg_x);\r
+                    calc_adl    := ("0" & reg_idl_l) + ("0" & reg_x);\r
                 elsif (reg_inst = conv_std_logic_vector(16#9d#, 8)) then\r
                     --sta, x\r
                     reg_addr    <= reg_idl_h & (reg_idl_l + reg_x);\r
@@ -1198,11 +1321,20 @@ end;
                     if (reg_inst(4 downto 2) = "111") then\r
                         --abs x\r
                         reg_addr    <= reg_idl_h & (reg_idl_l + reg_x);\r
+                        calc_adl    := ("0" & reg_idl_l) + ("0" & reg_x);\r
+                    end if; \r
+                elsif (reg_inst(1 downto 0) = "01") then\r
+                    --a2 inst\r
+                    if (reg_inst(4 downto 2) = "110") then\r
+                        --abs y\r
+                        reg_addr    <= reg_idl_h & (reg_idl_l + reg_y);\r
                         calc_adl    := ("0" & reg_idl_l) + ("0" & reg_y);\r
+                    elsif (reg_inst(4 downto 2) = "111") then\r
+                        --abs x\r
+                        reg_addr    <= reg_idl_h & (reg_idl_l + reg_x);\r
+                        calc_adl    := ("0" & reg_idl_l) + ("0" & reg_x);\r
                     end if; \r
                 end if;\r
-                reg_d_out   <= (others => 'Z');\r
-                reg_r_nw    <= '1';\r
 \r
                 reg_tmp_pg_crossed <= calc_adl(8);\r
             elsif (reg_main_state = ST_A27_T3 or\r
@@ -1210,15 +1342,11 @@ end;
                 --ind, y\r
                 --ial + 1 cycle.\r
                 reg_addr    <= "00000000" & (reg_idl_l + 1);\r
-                reg_d_out   <= (others => 'Z');\r
-                reg_r_nw    <= '1';\r
             elsif (reg_main_state = ST_A27_T4 or\r
                 reg_main_state = ST_A36_T4) then\r
                 --ind, y\r
                 --bal + y cycle.\r
                 reg_addr    <= reg_tmp_h & (reg_tmp_l + reg_y);\r
-                reg_d_out   <= (others => 'Z');\r
-                reg_r_nw    <= '1';\r
                 calc_adl    := ("0" & reg_tmp_l) + ("0" & reg_y);\r
                 reg_tmp_pg_crossed <= calc_adl(8);\r
             elsif (reg_main_state = ST_A51_T1 or\r
@@ -1226,17 +1354,12 @@ end;
                 --push/pull\r
                 --discard pc cycle.\r
                 reg_addr    <= reg_pc_h & (reg_pc_l + 1);\r
-                reg_d_out   <= (others => 'Z');\r
-                reg_r_nw    <= '1';\r
             elsif (reg_main_state = ST_A52_T2 or\r
                 reg_main_state = ST_A53_T2\r
                 ) then\r
                 --pull, jsr\r
                 --discard sp cycle.\r
                 reg_addr    <= "00000001" & reg_sp;\r
-                reg_d_out   <= (others => 'Z');\r
-                reg_r_nw    <= '1';\r
-\r
 \r
 \r
            --a2 instructions.\r
@@ -1248,8 +1371,6 @@ end;
                 reg_main_state = ST_A27_T5\r
             ) then\r
                 --execute cycle.\r
-                reg_d_out   <= (others => 'Z');\r
-                reg_r_nw    <= '1';\r
 \r
                 --address bus out.\r
                 if (reg_main_state = ST_A22_T2) then\r
@@ -1329,15 +1450,7 @@ end;
                 end if;\r
 \r
                 --rw ctrl\r
-                if (reg_sub_state = ST_SUB32 or\r
-                    reg_sub_state = ST_SUB33 or\r
-                    reg_sub_state = ST_SUB40 or\r
-                    reg_sub_state = ST_SUB41\r
-                    ) then\r
-                    reg_r_nw    <= '0';\r
-                else\r
-                    reg_r_nw    <= 'Z';\r
-                end if;\r
+                write_enable;\r
 \r
                 --address bus out.\r
                 if (reg_main_state = ST_A31_T2) then\r
@@ -1390,8 +1503,6 @@ end;
                 reg_main_state = ST_A44_T4\r
             ) then\r
                 --data fetch cycle.\r
-                reg_d_out   <= (others => 'Z');\r
-                reg_r_nw    <= '1';\r
 \r
                 --address bus out.\r
                 if (reg_main_state = ST_A41_T2) then\r
@@ -1423,17 +1534,7 @@ end;
                 --data store cycle.\r
                 --data out\r
                 reg_d_out   <= reg_tmp_data;\r
-\r
-                --rw ctrl\r
-                if (reg_sub_state = ST_SUB32 or\r
-                    reg_sub_state = ST_SUB33 or\r
-                    reg_sub_state = ST_SUB40 or\r
-                    reg_sub_state = ST_SUB41\r
-                    ) then\r
-                    reg_r_nw    <= '0';\r
-                else\r
-                    reg_r_nw    <= 'Z';\r
-                end if;\r
+                write_enable;\r
 \r
                 --address bus out.\r
                 if (reg_main_state = ST_A41_T3 or\r
@@ -1465,15 +1566,6 @@ end;
             --push\r
             elsif (reg_main_state = ST_A51_T2) then\r
                 reg_addr    <= "00000001" & reg_sp;\r
-                if (reg_sub_state = ST_SUB32 or\r
-                    reg_sub_state = ST_SUB33 or\r
-                    reg_sub_state = ST_SUB40 or\r
-                    reg_sub_state = ST_SUB41\r
-                    ) then\r
-                    reg_r_nw    <= '0';\r
-                else\r
-                    reg_r_nw    <= 'Z';\r
-                end if;\r
                 if (reg_inst = conv_std_logic_vector(16#48#, 8)) then\r
                     --pha\r
                     reg_d_out   <= reg_acc;\r
@@ -1481,46 +1573,29 @@ end;
                     --php\r
                     reg_d_out   <= reg_status;\r
                 end if;\r
+                write_enable;\r
 \r
             --pull\r
             elsif (reg_main_state = ST_A52_T3) then\r
                 reg_addr    <= "00000001" & reg_sp;\r
-                reg_r_nw    <= '1';\r
-                reg_d_out   <= (others => 'Z');\r
 \r
             --jsr.\r
             elsif (reg_main_state = ST_A53_T3) then\r
                 --push pch\r
                 reg_addr    <= "00000001" & reg_sp;\r
                 reg_d_out   <= reg_pc_h;\r
-                if (reg_sub_state = ST_SUB32 or\r
-                    reg_sub_state = ST_SUB33 or\r
-                    reg_sub_state = ST_SUB40 or\r
-                    reg_sub_state = ST_SUB41\r
-                    ) then\r
-                    reg_r_nw    <= '0';\r
-                else\r
-                    reg_r_nw    <= 'Z';\r
-                end if;\r
+                write_enable;\r
             elsif (reg_main_state = ST_A53_T4) then\r
                 --push pcl\r
                 reg_addr    <= "00000001" & reg_sp;\r
                 reg_d_out   <= reg_pc_l;\r
-                if (reg_sub_state = ST_SUB32 or\r
-                    reg_sub_state = ST_SUB33 or\r
-                    reg_sub_state = ST_SUB40 or\r
-                    reg_sub_state = ST_SUB41\r
-                    ) then\r
-                    reg_r_nw    <= '0';\r
-                else\r
-                    reg_r_nw    <= 'Z';\r
-                end if;\r
+                write_enable;\r
             elsif (reg_main_state = ST_A53_T5) then\r
                 if (reg_sub_state = ST_SUB00) then\r
                     --fetch next.\r
                     reg_addr    <= reg_pc_h & reg_pc_l;\r
                     reg_d_out   <= (others => 'Z');\r
-                    reg_r_nw    <= '1';\r
+                    reg_oe_n    <= '0';\r
                 elsif (reg_sub_state = ST_SUB70) then\r
                     --go to sub-routine addr.\r
                     reg_pc_l    <= reg_idl_l;\r
@@ -1532,8 +1607,6 @@ end;
                 if (reg_sub_state = ST_SUB00) then\r
                     --fetch next.\r
                     reg_addr    <= reg_pc_h & reg_pc_l;\r
-                    reg_d_out   <= (others => 'Z');\r
-                    reg_r_nw    <= '1';\r
                 elsif (reg_sub_state = ST_SUB70) then\r
                     reg_pc_l    <= reg_idl_l;\r
                     reg_pc_h    <= reg_idl_h;\r
@@ -1543,16 +1616,12 @@ end;
             elsif (reg_main_state = ST_A562_T3) then\r
                 if (reg_sub_state = ST_SUB00) then\r
                     reg_addr    <= (reg_idl_h & reg_idl_l);\r
-                    reg_d_out   <= (others => 'Z');\r
-                    reg_r_nw    <= '1';\r
                 elsif (reg_sub_state = ST_SUB70) then\r
                     reg_pc_l    <= reg_d_in;\r
                 end if;\r
             elsif (reg_main_state = ST_A562_T4) then\r
                 if (reg_sub_state = ST_SUB00) then\r
                     reg_addr    <= (reg_idl_h & reg_idl_l) + 1;\r
-                    reg_d_out   <= (others => 'Z');\r
-                    reg_r_nw    <= '1';\r
                 elsif (reg_sub_state = ST_SUB70) then\r
                     reg_pc_h    <= reg_d_in;\r
                 end if;\r
@@ -1561,14 +1630,10 @@ end;
             elsif (reg_main_state = ST_A57_T2) then\r
                 --sp out (discarded.)\r
                 reg_addr    <= "00000001" & reg_sp;\r
-                reg_d_out   <= (others => 'Z');\r
-                reg_r_nw    <= '1';\r
             elsif (reg_main_state = ST_A57_T3) then\r
                 --pull pcl\r
                 if (reg_sub_state = ST_SUB00) then\r
                     reg_addr    <= "00000001" & reg_sp;\r
-                    reg_d_out   <= (others => 'Z');\r
-                    reg_r_nw    <= '1';\r
                 elsif (reg_sub_state = ST_SUB70) then\r
                     reg_pc_l    <= reg_d_in;\r
                 end if;\r
@@ -1576,8 +1641,6 @@ end;
                 --pull pch\r
                 if (reg_sub_state = ST_SUB00) then\r
                     reg_addr    <= "00000001" & reg_sp;\r
-                    reg_d_out   <= (others => 'Z');\r
-                    reg_r_nw    <= '1';\r
                 elsif (reg_sub_state = ST_SUB70) then\r
                     reg_pc_h    <= reg_d_in;\r
                 end if;\r
@@ -1585,32 +1648,96 @@ end;
                 --pc out (discarded.)\r
                 if (reg_sub_state = ST_SUB00) then\r
                     reg_addr    <= reg_pc_h & reg_pc_l;\r
-                    reg_d_out   <= (others => 'Z');\r
-                    reg_r_nw    <= '1';\r
                 elsif (reg_sub_state = ST_SUB70) then\r
-                    reg_pc_l    <= reg_pc_l + 1;\r
+                    pc_inc;\r
                 end if;\r
 \r
-           --conditional branch.\r
+            --conditional branch.\r
             elsif (reg_main_state = ST_A58_T2) then\r
                 if (reg_sub_state = ST_SUB10) then\r
                     calc_adl    := ("0" & reg_pc_l) + ("0" & reg_idl_l);\r
-                    reg_tmp_pg_crossed <= calc_adl(8);\r
+                    --conditional branch is signed add.\r
+                    if ((reg_idl_l(7) xor calc_adl(8)) = '1') then\r
+                        reg_tmp_pg_crossed <= '1';\r
+                    else\r
+                        reg_tmp_pg_crossed <= '0';\r
+                    end if;\r
 \r
                     reg_pc_l    <= calc_adl(7 downto 0);\r
                     reg_addr    <= reg_pc_h & calc_adl(7 downto 0);\r
-                    reg_d_out   <= (others => 'Z');\r
-                    reg_r_nw    <= '1';\r
                 end if;\r
 \r
             --page crossed.\r
             elsif (reg_main_state = ST_A58_T3) then\r
                 if (reg_sub_state = ST_SUB10) then\r
-                    reg_pc_l    <= reg_pc_h + "1";\r
-                    reg_addr    <= (reg_pc_h + "1") & reg_pc_l;\r
-                    reg_d_out   <= (others => 'Z');\r
-                    reg_r_nw    <= '1';\r
+                    if (reg_idl_l(7) = '0') then\r
+                        --page crossig forward branch.\r
+                        reg_pc_h    <= reg_pc_h + "1";\r
+                        reg_addr    <= (reg_pc_h + "1") & reg_pc_l;\r
+                    else\r
+                        --page crossig backward branch.\r
+                        reg_pc_h    <= reg_pc_h - "1";\r
+                        reg_addr    <= (reg_pc_h - "1") & reg_pc_l;\r
+                    end if;\r
+                end if;\r
+\r
+            --nmi\r
+            elsif (reg_main_state = ST_NM_T1) then\r
+                reg_inst    <= (others => '0');\r
+                reg_addr    <= (others => '0');\r
+                reg_d_out   <= (others => 'Z');\r
+                reg_oe_n    <= '1';\r
+                reg_we_n    <= '1';\r
+            elsif (reg_main_state = ST_NM_T3) then\r
+                --push pch.\r
+                reg_addr    <= "00000001" & reg_sp;\r
+                reg_d_out   <= reg_pc_h;\r
+                write_enable;\r
+            elsif (reg_main_state = ST_NM_T4) then\r
+                --push pcl.\r
+                reg_addr    <= "00000001" & reg_sp;\r
+                reg_d_out   <= reg_pc_l;\r
+                write_enable;\r
+            elsif (reg_main_state = ST_NM_T5) then\r
+                --push status.\r
+                reg_addr    <= "00000001" & reg_sp;\r
+                reg_d_out   <= reg_status;\r
+                write_enable;\r
+            elsif (reg_main_state = ST_NM_T6) then\r
+                --vector low...\r
+                reg_addr    <= "1111111111111010";\r
+                reg_d_out   <= (others => 'Z');\r
+                reg_oe_n    <= '0';\r
+                reg_we_n    <= '1';\r
+                reg_pc_l    <= reg_d_in;\r
+            elsif (reg_main_state = ST_NM_T7) then\r
+                --vector high...\r
+                reg_addr    <= "1111111111111011";\r
+                reg_pc_h    <= reg_d_in;\r
+\r
+           --rti.\r
+            elsif (reg_main_state = ST_A55_T2) then\r
+                --sp out (discarded.)\r
+                reg_addr    <= "00000001" & reg_sp;\r
+            elsif (reg_main_state = ST_A55_T3) then\r
+                --pull status\r
+                reg_addr    <= "00000001" & reg_sp;\r
+            elsif (reg_main_state = ST_A55_T4) then\r
+                --pull pcl\r
+                if (reg_sub_state = ST_SUB00) then\r
+                    reg_addr    <= "00000001" & reg_sp;\r
+                elsif (reg_sub_state = ST_SUB70) then\r
+                    reg_pc_l    <= reg_d_in;\r
+                end if;\r
+            elsif (reg_main_state = ST_A55_T5) then\r
+                --pull pch\r
+                if (reg_sub_state = ST_SUB00) then\r
+                    reg_addr    <= "00000001" & reg_sp;\r
+                elsif (reg_sub_state = ST_SUB70) then\r
+                    reg_pc_h    <= reg_d_in;\r
                 end if;\r
+\r
+\r
             end if;--if (reg_main_state = ST_RS_T0) then\r
         end if;--if (pi_rst_n = '0') then\r
     end process;\r
@@ -1695,24 +1822,31 @@ end;
     sp_p : process (pi_rst_n, pi_base_clk)\r
     begin\r
         if (pi_rst_n = '0') then\r
-            reg_sp <= (others => '0');\r
+            reg_sp <= INIT_SP;\r
         elsif (rising_edge(pi_base_clk)) then\r
             if (reg_main_state = ST_A1_T1) then\r
                 --txs inst.\r
                 if (reg_inst = conv_std_logic_vector(16#9a#, 8)) then\r
-                    reg_sp <= reg_idl_l;\r
+                    reg_sp <= reg_x;\r
                 end if;\r
             elsif (reg_main_state = ST_A51_T2 or\r
                 reg_main_state = ST_A53_T3 or\r
-                reg_main_state = ST_A53_T4) then\r
-                --push, jsr.\r
+                reg_main_state = ST_A53_T4 or\r
+                reg_main_state = ST_NM_T3 or\r
+                reg_main_state = ST_NM_T4 or\r
+                reg_main_state = ST_NM_T5\r
+                ) then\r
+                --push, jsr, nmi.\r
                 if (reg_sub_state = ST_SUB70) then\r
                     reg_sp <= reg_sp - 1;\r
                 end if;\r
             elsif (reg_main_state = ST_A52_T2 or\r
+                reg_main_state = ST_A55_T2 or\r
+                reg_main_state = ST_A55_T3 or\r
+                reg_main_state = ST_A55_T4 or\r
                 reg_main_state = ST_A57_T2 or\r
                 reg_main_state = ST_A57_T3) then\r
-                --pull, rts.\r
+                --pull, rts, rti.\r
                 if (reg_sub_state = ST_SUB70) then\r
                     reg_sp <= reg_sp + 1;\r
                 end if;\r
@@ -1766,16 +1900,16 @@ end;
     begin\r
         --Most instructions that explicitly reference memory locations have bit patterns of the form aaabbbcc.\r
         if (pi_rst_n = '0') then\r
-            reg_acc <= (others => '0');\r
-            reg_x <= (others => '0');\r
-            reg_y <= (others => '0');\r
-            reg_status <= (others => '0');\r
+            reg_acc <= INIT_ACC;\r
+            reg_x <= INIT_X;\r
+            reg_y <= INIT_Y;\r
+            reg_status <= INIT_STATUS;\r
             reg_tmp_carry <= '0';\r
             reg_tmp_ovf <= '0';\r
             reg_tmp_condition <= '0';\r
         elsif (rising_edge(pi_base_clk)) then\r
             --not used status pin initialize (to avoid latches).\r
-            reg_status(5 downto 3) <= "000";\r
+            reg_status(5 downto 3) <= "100";\r
 \r
             --a1 instructions...\r
             --asl   dex     nop     tax     tya\r
@@ -1930,9 +2064,10 @@ end;
                 reg_main_state = ST_A22_T2 or\r
                 reg_main_state = ST_A23_T3 or\r
                 reg_main_state = ST_A24_T5 or\r
-                reg_main_state = ST_A25_T4 or\r
                 reg_main_state = ST_A25_T3 or\r
+                reg_main_state = ST_A25_T4 or\r
                 reg_main_state = ST_A26_T3 or\r
+                reg_main_state = ST_A27_T4 or\r
                 reg_main_state = ST_A27_T5) then\r
                 \r
                 --update reg\r
@@ -1970,7 +2105,7 @@ end;
                             calc_res := ("0" & reg_acc) - ("0" & reg_d_in) - not reg_status(FL_C);\r
 \r
                             --c Set if unsigned borrow not required; cleared if unsigned borrow.\r
-                            reg_tmp_carry <= not calc_res(7);\r
+                            reg_tmp_carry <= not calc_res(8);\r
                             --v Set if signed borrow required; cleared if no signed borrow.\r
                             if ((reg_acc(7) /= reg_d_in(7)) and (reg_acc(7) /= calc_res(7))) then\r
                                 reg_tmp_ovf <= '1';\r
@@ -2241,9 +2376,69 @@ end;
                         set_condition_result(FL_V, '1');\r
                     end if;\r
                 end if;\r
+\r
+            elsif (reg_main_state = ST_A55_T3) then\r
+                --rti, pull status reg.\r
+                if (reg_sub_state = ST_SUB30) then\r
+                    reg_status <= reg_d_in;\r
+                end if;--if (reg_sub_state = ST_SUB30) then\r
+\r
+\r
             end if;--if (reg_main_state = ST_A21_T1 or...\r
         end if;--if (pi_rst_n = '0') then\r
     end process;\r
 \r
+    --nmi handled flag process...\r
+    nmi_handle_p : process (pi_rst_n, pi_base_clk)\r
+    begin\r
+        if (pi_rst_n = '0') then\r
+            reg_nmi_handled <= 0;\r
+        elsif (rising_edge(pi_base_clk)) then\r
+            if (pi_nmi_n = '1') then\r
+                reg_nmi_handled <= 0;\r
+            elsif (reg_main_state = ST_NM_T7 and reg_sub_state = ST_SUB73) then\r
+                reg_nmi_handled <= 1;\r
+            end if;\r
+        end if;--if (pi_rst_n = '0') then\r
+    end process;\r
+\r
+    --dma flag process...\r
+    dma_set_p : process (pi_rst_n, pi_base_clk)\r
+    begin\r
+        if (pi_rst_n = '0') then\r
+            reg_dma_set <= 0;\r
+        elsif (rising_edge(pi_base_clk)) then\r
+            if (pi_rdy = '0') then\r
+                reg_dma_set <= 1;\r
+            elsif (reg_main_state = ST_CM_T0) then\r
+                reg_dma_set <= 0;\r
+            end if;\r
+        end if;--if (pi_rst_n = '0') then\r
+    end process;\r
+\r
+    --debug cnt...\r
+    po_exc_cnt <= reg_exc_cnt;\r
+    exc_cnt_p : process (pi_rst_n, pi_base_clk)\r
+    begin\r
+        if (pi_rst_n = '0') then\r
+            if (DEBUG_SW = 0) then\r
+                reg_exc_cnt <= (others => '0');\r
+            else\r
+                --for test....\r
+                reg_exc_cnt <= INIT_EXC_CNT;\r
+            end if;\r
+        else\r
+            if (rising_edge(pi_base_clk)) then\r
+                if (reg_main_state = ST_CM_T0 and reg_sub_state = ST_SUB73) then\r
+                    reg_exc_cnt <= reg_exc_cnt + 1;\r
+                elsif (reg_main_state = ST_NM_T7 and reg_sub_state = ST_SUB73) then\r
+                    --reg_exc_cnt upper 16 bit is nmi count.\r
+                    --lower 48 bit is cpu exec count from nmi initiated.\r
+                    reg_exc_cnt(47 downto 0) <= (others => '0');\r
+                    reg_exc_cnt(63 downto 48) <= reg_exc_cnt(63 downto 48) + 1;\r
+                end if;\r
+            end if;\r
+        end if;\r
+    end process;\r
 end rtl;\r
 \r