OSDN Git Service

nmi ok.
authorastoria-d <astoria-d@mail.goo.ne.jp>
Thu, 22 Sep 2016 04:55:26 +0000 (13:55 +0900)
committerastoria-d <astoria-d@mail.goo.ne.jp>
Thu, 22 Sep 2016 04:55:26 +0000 (13:55 +0900)
de0_cv_nes/mos6502.vhd

index 5a8876e..0119c12 100644 (file)
@@ -389,6 +389,7 @@ begin
             when ST_CM_T0 =>\r
                 if (reg_sub_state = ST_SUB73) then\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
                     else\r
                         ---instruction decode next state.\r
@@ -1080,6 +1081,20 @@ 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
@@ -1108,19 +1123,19 @@ end;
                 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_addr    <= "00000001" & reg_sp;\r
                 reg_d_out   <= (others => '0');\r
-                reg_we_n    <= '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_addr    <= "00000001" & (reg_sp - 1);\r
                 reg_d_out   <= (others => '0');\r
-                reg_we_n    <= '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_addr    <= "00000001" & (reg_sp - 2);\r
                 reg_d_out   <= (others => '0');\r
-                reg_we_n    <= '0';\r
+                write_enable;\r
             elsif (reg_main_state = ST_RS_T6) then\r
                 --reset vector low...\r
                 reg_addr    <= "1111111111111100";\r
@@ -1383,16 +1398,7 @@ end;
                 end if;\r
 \r
                 --rw ctrl\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
+                write_enable;\r
 \r
                 --address bus out.\r
                 if (reg_main_state = ST_A31_T2) then\r
@@ -1476,18 +1482,7 @@ end;
                 --data store cycle.\r
                 --data out\r
                 reg_d_out   <= reg_tmp_data;\r
-                reg_oe_n    <= '1';\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_we_n    <= '0';\r
-                else\r
-                    reg_we_n    <= '1';\r
-                end if;\r
+                write_enable;\r
 \r
                 --address bus out.\r
                 if (reg_main_state = ST_A41_T3 or\r
@@ -1519,7 +1514,6 @@ end;
             --push\r
             elsif (reg_main_state = ST_A51_T2) then\r
                 reg_addr    <= "00000001" & reg_sp;\r
-                reg_oe_n    <= '1';\r
                 if (reg_inst = conv_std_logic_vector(16#48#, 8)) then\r
                     --pha\r
                     reg_d_out   <= reg_acc;\r
@@ -1527,15 +1521,7 @@ end;
                     --php\r
                     reg_d_out   <= reg_status;\r
                 end if;\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
+                write_enable;\r
 \r
             --pull\r
             elsif (reg_main_state = ST_A52_T3) then\r
@@ -1546,29 +1532,12 @@ end;
                 --push pch\r
                 reg_addr    <= "00000001" & reg_sp;\r
                 reg_d_out   <= reg_pc_h;\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
+                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_we_n    <= '0';\r
-                else\r
-                    reg_we_n    <= '1';\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
@@ -1659,6 +1628,40 @@ end;
                         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
             end if;--if (reg_main_state = ST_RS_T0) then\r
         end if;--if (pi_rst_n = '0') then\r
     end process;\r
@@ -1752,8 +1755,12 @@ end;
                 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