signal pc : std_logic_vector (asize - 1 downto 0);
signal instruction : std_logic_vector (dsize - 1 downto 0);
+
+-- SR Flags (bit 7 to bit 0):
+-- 7 N .... Negative
+-- 6 V .... Overflow
+-- 5 - .... ignored
+-- 4 B .... Break
+-- 3 D .... Decimal (use BCD for arithmetics)
+-- 2 I .... Interrupt (IRQ disable)
+-- 1 Z .... Zero
+-- 0 C .... Carry
+constant st_N : integer := 7;
+constant st_V : integer := 6;
+constant st_B : integer := 4;
+constant st_D : integer := 3;
+constant st_I : integer := 2;
+constant st_Z : integer := 1;
+constant st_C : integer := 0;
+
signal status_reg : std_logic_vector (dsize - 1 downto 0);
+
signal dbus_buffer : std_logic_vector (dsize - 1 downto 0);
signal reg_x : std_logic_vector (dsize - 1 downto 0);
signal reg_y : std_logic_vector (dsize - 1 downto 0);
+signal sp : std_logic_vector (dsize - 1 downto 0);
type dec_status is (reset0, reset1, reset2, reset3, reset4, reset5,
fetch, decode,
--addr(dsize - 1 downto 0) <= internal_abus_l;
main_p : process (rst_n, set_clk, trigger_clk)
+ variable single_inst : boolean;
begin
if (rst_n'event and rst_n = '0') then
d_print("reset negated.");
cur_status <= reset0;
+ status_reg <= (others => '0');
pc <= conv_std_logic_vector(16#8000#, asize);
end if;
---instruction consists of aaabbbcc form.
if cur_status = decode then
d_print("inst: " & conv_hex8(conv_integer(instruction)));
- if instruction (1 downto 0) = "01" then
- d_print("cc=01");
-
- ---bbb part format
- if instruction (4 downto 2) = "000" or
- instruction (4 downto 2) = "001" or
- instruction (4 downto 2) = "010" or
- instruction (4 downto 2) = "011" or
- instruction (4 downto 2) = "100" or
- instruction (4 downto 2) = "101" or
- instruction (4 downto 2) = "110" or
- instruction (4 downto 2) = "111" then
- if instruction (7 downto 5) = "000" then
- d_print("ora");
- elsif instruction (7 downto 5) = "001" then
- d_print("and");
- elsif instruction (7 downto 5) = "010" then
- d_print("eor");
- elsif instruction (7 downto 5) = "011" then
- d_print("adc");
- elsif instruction (7 downto 5) = "100" then
- d_print("sta");
- elsif instruction (7 downto 5) = "101" then
- d_print("lda");
- elsif instruction (7 downto 5) = "110" then
- d_print("cmp");
- elsif instruction (7 downto 5) = "111" then
- d_print("sbc");
- else
- assert false
- report ("unknow instruction") severity failure;
+ ---rest of single byte instruction.
+ single_inst := false;
+
+ if instruction = conv_std_logic_vector(16#8a#, dsize) then
+ single_inst := true;
+ d_print("txa");
+ elsif instruction = conv_std_logic_vector(16#9a#, dsize) then
+ single_inst := true;
+ d_print("txs");
+ sp <= reg_x;
+ elsif instruction = conv_std_logic_vector(16#aa#, dsize) then
+ single_inst := true;
+ d_print("tax");
+ elsif instruction = conv_std_logic_vector(16#ba#, dsize) then
+ single_inst := true;
+ d_print("tsx");
+ elsif instruction = conv_std_logic_vector(16#ca#, dsize) then
+ single_inst := true;
+ d_print("dex");
+ elsif instruction = conv_std_logic_vector(16#ea#, dsize) then
+ single_inst := true;
+ d_print("nop");
+ elsif instruction = conv_std_logic_vector(16#08#, dsize) then
+ single_inst := true;
+ d_print("php");
+ elsif instruction = conv_std_logic_vector(16#28#, dsize) then
+ single_inst := true;
+ d_print("plp");
+ elsif instruction = conv_std_logic_vector(16#48#, dsize) then
+ single_inst := true;
+ d_print("pha");
+ elsif instruction = conv_std_logic_vector(16#68#, dsize) then
+ single_inst := true;
+ d_print("pla");
+ elsif instruction = conv_std_logic_vector(16#88#, dsize) then
+ single_inst := true;
+ d_print("dey");
+ elsif instruction = conv_std_logic_vector(16#a8#, dsize) then
+ single_inst := true;
+ d_print("tay");
+ elsif instruction = conv_std_logic_vector(16#c8#, dsize) then
+ single_inst := true;
+ d_print("iny");
+ elsif instruction = conv_std_logic_vector(16#e8#, dsize) then
+ single_inst := true;
+ d_print("inx");
+ elsif instruction = conv_std_logic_vector(16#18#, dsize) then
+ single_inst := true;
+ d_print("clc");
+ elsif instruction = conv_std_logic_vector(16#38#, dsize) then
+ single_inst := true;
+ d_print("sec");
+ elsif instruction = conv_std_logic_vector(16#58#, dsize) then
+ single_inst := true;
+ d_print("cli");
+ elsif instruction = conv_std_logic_vector(16#78#, dsize) then
+ single_inst := true;
+ d_print("sei");
+ status_reg(st_I) <= '1';
+ elsif instruction = conv_std_logic_vector(16#98#, dsize) then
+ single_inst := true;
+ d_print("tya");
+ elsif instruction = conv_std_logic_vector(16#b8#, dsize) then
+ single_inst := true;
+ d_print("clv");
+ elsif instruction = conv_std_logic_vector(16#d8#, dsize) then
+ single_inst := true;
+ d_print("cld");
+ elsif instruction = conv_std_logic_vector(16#f8#, dsize) then
+ single_inst := true;
+ d_print("sed");
+ end if;
+
+ if single_inst then
+ cur_status <= fetch;
+ cur_mode <= ad_imp;
+ addr <= (others => 'Z');
+ else
+
+ if instruction (1 downto 0) = "01" then
+ d_print("cc=01");
+
+ ---bbb part format
+ if instruction (4 downto 2) = "000" or
+ instruction (4 downto 2) = "001" or
+ instruction (4 downto 2) = "010" or
+ instruction (4 downto 2) = "011" or
+ instruction (4 downto 2) = "100" or
+ instruction (4 downto 2) = "101" or
+ instruction (4 downto 2) = "110" or
+ instruction (4 downto 2) = "111" then
+
+ if instruction (7 downto 5) = "000" then
+ d_print("ora");
+ elsif instruction (7 downto 5) = "001" then
+ d_print("and");
+ elsif instruction (7 downto 5) = "010" then
+ d_print("eor");
+ elsif instruction (7 downto 5) = "011" then
+ d_print("adc");
+ elsif instruction (7 downto 5) = "100" then
+ d_print("sta");
+ elsif instruction (7 downto 5) = "101" then
+ d_print("lda");
+ elsif instruction (7 downto 5) = "110" then
+ d_print("cmp");
+ elsif instruction (7 downto 5) = "111" then
+ d_print("sbc");
+ else
+ assert false
+ report ("unknow instruction") severity failure;
+ end if;
end if;
- else
- ---else single byte instruction.
- cur_status <= fetch;
- cur_mode <= ad_imp;
- addr <= (others => 'Z');
- if instruction = conv_std_logic_vector(16#8a#, dsize) then
- d_print("txa");
- elsif instruction = conv_std_logic_vector(16#9a#, dsize) then
- d_print("txs");
- elsif instruction = conv_std_logic_vector(16#aa#, dsize) then
- d_print("tax");
- elsif instruction = conv_std_logic_vector(16#ba#, dsize) then
- d_print("tsx");
- elsif instruction = conv_std_logic_vector(16#ca#, dsize) then
- d_print("dex");
- elsif instruction = conv_std_logic_vector(16#ea#, dsize) then
- d_print("nop");
+ elsif instruction (1 downto 0) = "10" then
+ d_print("cc=10");
+
+ if instruction (4 downto 2) = "000" then
+ cur_mode <= ad_imm;
+ d_print("immediate");
+ addr <= pc;
+ pc <= pc + 1;
+ cur_status <= exec0;
+ elsif instruction (4 downto 2) = "001" then
+ cur_mode <= ad_zp0;
+ elsif instruction (4 downto 2) = "010" then
+ cur_mode <= ad_acc;
+ elsif instruction (4 downto 2) = "011" then
+ cur_mode <= ad_abs0;
+ elsif instruction (4 downto 2) = "101" then
+ cur_mode <= ad_zpx0;
+ elsif instruction (4 downto 2) = "111" then
+ cur_mode <= ad_absx0;
else
- assert false
- report ("unknow instruction") severity failure;
+ cur_mode <= ad_unknown;
end if;
- end if;
- elsif instruction (1 downto 0) = "10" then
- d_print("cc=10");
-
- if instruction (4 downto 2) = "000" then
- cur_mode <= ad_imm;
- d_print("immediate");
- addr <= pc;
- pc <= pc + 1;
- cur_status <= exec0;
- elsif instruction (4 downto 2) = "001" then
- cur_mode <= ad_zp0;
- elsif instruction (4 downto 2) = "010" then
- cur_mode <= ad_acc;
- elsif instruction (4 downto 2) = "011" then
- cur_mode <= ad_abs0;
- elsif instruction (4 downto 2) = "101" then
- cur_mode <= ad_zpx0;
- elsif instruction (4 downto 2) = "111" then
- cur_mode <= ad_absx0;
- else
- cur_mode <= ad_unknown;
- end if;
-
- if instruction (7 downto 5) = "000" then
- d_print("asl");
- elsif instruction (7 downto 5) = "001" then
- d_print("rol");
- elsif instruction (7 downto 5) = "010" then
- d_print("lsr");
- elsif instruction (7 downto 5) = "011" then
- d_print("ror");
- elsif instruction (7 downto 5) = "100" then
- d_print("stx");
- elsif instruction (7 downto 5) = "101" then
- d_print("ldx");
- elsif instruction (7 downto 5) = "110" then
- d_print("dec");
- elsif instruction (7 downto 5) = "111" then
- d_print("inc");
- else
- assert false
- report ("unknow instruction") severity failure;
- end if;
- elsif instruction (1 downto 0) = "00" then
- d_print("cc=00 group...");
-
- if instruction (4 downto 0) = "10000" then
- ---conditional branch instruction..
-
- ---bbb part format
- elsif instruction (4 downto 2) = "000" or
- instruction (4 downto 2) = "001" or
- instruction (4 downto 2) = "011" or
- instruction (4 downto 2) = "101" or
- instruction (4 downto 2) = "111" then
-
- if instruction (7 downto 5) = "001" then
- d_print("bit");
+ if instruction (7 downto 5) = "000" then
+ d_print("asl");
+ elsif instruction (7 downto 5) = "001" then
+ d_print("rol");
elsif instruction (7 downto 5) = "010" then
- d_print("jmp");
+ d_print("lsr");
elsif instruction (7 downto 5) = "011" then
- d_print("jmp");
+ d_print("ror");
elsif instruction (7 downto 5) = "100" then
- d_print("sty");
+ d_print("stx");
elsif instruction (7 downto 5) = "101" then
- d_print("ldy");
+ d_print("ldx");
elsif instruction (7 downto 5) = "110" then
- d_print("cpy");
+ d_print("dec");
elsif instruction (7 downto 5) = "111" then
- d_print("cpx");
+ d_print("inc");
else
assert false
report ("unknow instruction") severity failure;
end if;
-
- else
- ---else single byte instruction.
- cur_status <= fetch;
- cur_mode <= ad_imp;
- addr <= (others => 'Z');
- if instruction = conv_std_logic_vector(16#08#, dsize) then
- d_print("php");
- elsif instruction = conv_std_logic_vector(16#28#, dsize) then
- d_print("plp");
- elsif instruction = conv_std_logic_vector(16#48#, dsize) then
- d_print("pha");
- elsif instruction = conv_std_logic_vector(16#68#, dsize) then
- d_print("pla");
- elsif instruction = conv_std_logic_vector(16#88#, dsize) then
- d_print("dey");
- elsif instruction = conv_std_logic_vector(16#a8#, dsize) then
- d_print("tay");
- elsif instruction = conv_std_logic_vector(16#c8#, dsize) then
- d_print("iny");
- elsif instruction = conv_std_logic_vector(16#e8#, dsize) then
- d_print("inx");
- elsif instruction = conv_std_logic_vector(16#18#, dsize) then
- d_print("clc");
- elsif instruction = conv_std_logic_vector(16#38#, dsize) then
- d_print("sec");
- elsif instruction = conv_std_logic_vector(16#58#, dsize) then
- d_print("cli");
- elsif instruction = conv_std_logic_vector(16#78#, dsize) then
- d_print("sei");
- elsif instruction = conv_std_logic_vector(16#98#, dsize) then
- d_print("tya");
- elsif instruction = conv_std_logic_vector(16#b8#, dsize) then
- d_print("clv");
- elsif instruction = conv_std_logic_vector(16#d8#, dsize) then
- d_print("cld");
- elsif instruction = conv_std_logic_vector(16#f8#, dsize) then
- d_print("sed");
- else
- assert false
- report ("unknow instruction") severity failure;
- end if;
- end if;
- end if;
- end if;
- end if;
+
+ elsif instruction (1 downto 0) = "00" then
+ d_print("cc=00 group...");
+
+ if instruction (4 downto 0) = "10000" then
+ ---conditional branch instruction..
+
+ ---bbb part format
+ elsif instruction (4 downto 2) = "000" or
+ instruction (4 downto 2) = "001" or
+ instruction (4 downto 2) = "011" or
+ instruction (4 downto 2) = "101" or
+ instruction (4 downto 2) = "111" then
+
+ if instruction (7 downto 5) = "001" then
+ d_print("bit");
+ elsif instruction (7 downto 5) = "010" then
+ d_print("jmp");
+ elsif instruction (7 downto 5) = "011" then
+ d_print("jmp");
+ elsif instruction (7 downto 5) = "100" then
+ d_print("sty");
+ elsif instruction (7 downto 5) = "101" then
+ d_print("ldy");
+ elsif instruction (7 downto 5) = "110" then
+ d_print("cpy");
+ elsif instruction (7 downto 5) = "111" then
+ d_print("cpx");
+ else
+ assert false
+ report ("unknow instruction") severity failure;
+ end if;
+ end if; --if instruction (4 downto 0) = "10000"
+ end if; --if instruction (1 downto 0) = "01"
+
+ end if; --if single_inst
+
+ end if; --if cur_status = decode
+ end if; --if (set_clk'event and set_clk = '1')
if (trigger_clk'event and trigger_clk = '1') then
--d_print("_");