--------- signals for address calucuration ----------
signal al_buf_we_n : std_logic;
signal ah_buf_we_n : std_logic;
+signal tmp_buf_we_n : std_logic;
signal al_reg_in : std_logic_vector (dsize - 1 downto 0);
signal ah_reg_in : std_logic_vector (dsize - 1 downto 0);
+signal tmp_reg_in : std_logic_vector (dsize - 1 downto 0);
signal al_reg : std_logic_vector (dsize - 1 downto 0);
signal ah_reg : std_logic_vector (dsize - 1 downto 0);
+signal tmp_reg : std_logic_vector (dsize - 1 downto 0);
signal a_sel : std_logic_vector (1 downto 0);
port map(clk, '1', '1', al_buf_we_n, al_reg_in, al_reg);
ah_dff : d_flip_flop generic map (dsize)
port map(clk, '1', '1', ah_buf_we_n, ah_reg_in, ah_reg);
+ tmp_dff : d_flip_flop generic map (dsize)
+ port map(clk, '1', '1', tmp_buf_we_n, tmp_reg_in, tmp_reg);
--pcl carry flag set.
pcl_carry_reg_in <= addr_c when pcl_inc_n = '0' else
pcl_inc_n, pch_inc_n, sp_oe_n, sp_push_n, sp_pop_n,
abs_xy_n, pg_next_n, zp_n, zp_xy_n, rel_calc_n,
indir_n, indir_x_n, indir_y_n,
- index_bus, bal, bah, addr_c_in, addr_out, addr_c,
+ index_bus, bal, bah,
--for arithmatic operation.
arith_en_n,
instruction, exec_cycle, int_d_bus, acc_out,
- carry_in, n, z, c, v,
- arith_reg, arith_reg_out, alu_out, d_out
+ carry_in, n, z, c, v
)
constant ADDR_ADC : std_logic_vector (1 downto 0) := "00";
----- address calcuration -----
-------------------------------
if (pcl_inc_n = '0') then
+ ea_carry <= '0';
a_sel <= ADDR_INC;
addr1 <= bal;
addr_back <= addr_out;
abh <= bah;
elsif (pch_inc_n = '0') then
+ ea_carry <= '0';
a_sel <= ADDR_INC;
addr1 <= bah;
addr_back <= addr_out;
elsif (sp_oe_n = '0') then
--stack operation...
abh <= "00000001";
+ ea_carry <= '0';
if (sp_push_n /= '0' and sp_pop_n /= '0') then
abl <= bal;
end if;
end if;
elsif (zp_n = '0') then
+ ea_carry <= '0';
if (zp_xy_n <= '0') then
a_sel <= ADDR_ADC;
addr1 <= bal;
a_sel <= ADDR_INC;
abl <= addr_out;
- --TODO: must handle page crossing case...
ea_carry <= addr_c;
elsif (indir_x_n = '0') then
+ if (exec_cycle = T2) then
+ ---input is IAL, but this cycle doesn't do anything....
+ abh <= "00000000";
+ abl <= bal;
+
+ --save base addr.
+ tmp_buf_we_n <= '0';
+ tmp_reg_in <= bal;
+ elsif (exec_cycle = T3) then
+
+ ---add x reg.
+ a_sel <= ADDR_ADC;
+ addr1 <= tmp_reg;
+ addr2 <= index_bus;
+ addr_c_in <= '0';
+
+ --save base addr.
+ tmp_buf_we_n <= '0';
+ tmp_reg_in <= addr_out;
+
+ --output @IAL+x
+ abh <= "00000000";
+ abl <= addr_out;
+
+ ---save BAL.
+ al_buf_we_n <= '0';
+ al_reg_in <= int_d_bus;
+
+ elsif (exec_cycle = T4) then
+ al_buf_we_n <= '1';
+ tmp_buf_we_n <= '1';
+
+ ---increment.
+ a_sel <= ADDR_INC;
+ addr1 <= tmp_reg;
+
+ --output @IAL+x
+ abh <= "00000000";
+ abl <= addr_out;
+
+ ---save BAH.
+ ah_buf_we_n <= '0';
+ ah_reg_in <= int_d_bus;
+ elsif (exec_cycle = T5 or exec_cycle = T0) then
+ ah_buf_we_n <= '1';
+
+ --output ah/al reg.
+ abh <= ah_reg;
+ abl <= al_reg;
+ end if; -- if (exec_cycle = T2) then
elsif (indir_y_n = '0') then
- if (clk = '0') then
if (exec_cycle = T2) then
---input is IAL.
abh <= "00000000";
---save BAL.
al_buf_we_n <= '0';
al_reg_in <= int_d_bus;
+ ea_carry <= '0';
+
+ --get next address (IAL + 1)
+ a_sel <= ADDR_INC;
+ addr1 <= bal;
+ tmp_buf_we_n <= '0';
+ tmp_reg_in <= addr_out;
elsif (exec_cycle = T3) then
al_buf_we_n <= '1';
+ tmp_buf_we_n <= '1';
abh <= "00000000";
--input is IAL + 1
- a_sel <= ADDR_INC;
- addr1 <= bal;
- abl <= addr_out;
+ abl <= tmp_reg;
---save BAH.
ah_buf_we_n <= '0';
ah_reg_in <= int_d_bus;
+ ea_carry <= addr_c;
elsif (exec_cycle = T4) then
+ ah_buf_we_n <= '1';
---add y reg.
a_sel <= ADDR_ADC;
---save the address.
al_buf_we_n <= '0';
al_reg_in <= addr_out;
- ah_buf_we_n <= '0';
- ah_reg_in <= ah_reg;
- elsif (exec_cycle = T0 and pg_next_n = '0') then
+ tmp_buf_we_n <= '0';
+ tmp_reg_in <= ah_reg;
+ elsif (exec_cycle = T5 or exec_cycle = T0) then
+ al_buf_we_n <= '1';
+ tmp_buf_we_n <= '1';
+ ea_carry <= '0';
+
+ if (pg_next_n = '0') then
+ a_sel <= ADDR_INC;
+ addr1 <= tmp_reg;
+ ---next page.
+ abh <= addr_out;
+ abl <= al_reg;
+ else
+ abh <= tmp_reg;
+ abl <= al_reg;
+ end if;
+ else
+ al_buf_we_n <= '1';
+ ah_buf_we_n <= '1';
+ tmp_buf_we_n <= '1';
ea_carry <= '0';
- a_sel <= ADDR_INC;
- addr1 <= ah_reg;
- ---next page.
- abh <= addr_out;
- abl <= al_reg;
end if; -- if (exec_cycle = T2) then
- end if; --if (clk = '0') then
else
al_buf_we_n <= '1';
ah_buf_we_n <= '1';
+ tmp_buf_we_n <= '1';
+ ea_carry <= '0';
abl <= bal;
abh <= bah;
--011 absolute
--101 zero page,X
--111 absolute,X
- if ((exec_cycle = T3 and instruction (4 downto 2) = "001") or
+ if ((exec_cycle = T2 and instruction (4 downto 2) = "001") or
+ (exec_cycle = T3 and instruction (4 downto 2) = "011") or
+ (exec_cycle = T3 and instruction (4 downto 2) = "101") or
+ (exec_cycle = T4 and instruction (4 downto 2) = "111")) then
+ arith_buf_we_n <= '0';
+ arith_reg_in <= int_d_bus;
+
+ elsif ((exec_cycle = T3 and instruction (4 downto 2) = "001") or
(exec_cycle = T4 and instruction (4 downto 2) = "011") or
(exec_cycle = T4 and instruction (4 downto 2) = "101") or
(exec_cycle = T5 and instruction (4 downto 2) = "111")) then
--first cycle. keep input variable.
--d_print("inc first.");
- arith_buf_we_n <= '0';
+ arith_buf_we_n <= '1';
+
arith_buf_oe_n <= '1';
d_oe_n <= '1';
- arith_reg_in <= int_d_bus;
d1 <= arith_reg;
else
--second cycle read from register, output modified data.