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
--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
--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
--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
--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
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
\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
--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
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
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
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
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
--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
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
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
--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
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
--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
--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
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
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
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
--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
--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
--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
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
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
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
--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
--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
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
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
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
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
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