From 215dad960247ccf0b230b6223a0a142ff7f5d5f4 Mon Sep 17 00:00:00 2001 From: Gyorgy Szombathelyi Date: Fri, 31 Aug 2018 23:51:06 +0200 Subject: [PATCH] C16: replace the 1541 CPU (again) - Use the CPU from 1541UltimateII project - Remove unnecessary hacks for the VIA chip from c1541_logic --- cores/c16/1541ultimate2cpu/alu.vhd | 137 +++++ cores/c16/1541ultimate2cpu/bit_cpx_cpy.vhd | 66 +++ cores/c16/1541ultimate2cpu/cpu6502.vhd | 55 ++ cores/c16/1541ultimate2cpu/data_oper.vhd | 193 +++++++ cores/c16/1541ultimate2cpu/implied.vhd | 114 +++++ .../c16/1541ultimate2cpu/pkg_6502_decode.vhd | 248 +++++++++ cores/c16/1541ultimate2cpu/pkg_6502_defs.vhd | 18 + .../c16/1541ultimate2cpu/pkg_6502_opcodes.vhd | 88 ++++ cores/c16/1541ultimate2cpu/proc_control.vhd | 472 ++++++++++++++++++ cores/c16/1541ultimate2cpu/proc_core.vhd | 233 +++++++++ cores/c16/1541ultimate2cpu/proc_interrupt.vhd | 83 +++ cores/c16/1541ultimate2cpu/proc_registers.vhd | 303 +++++++++++ cores/c16/1541ultimate2cpu/shifter.vhd | 60 +++ cores/c16/c1541/c1541_logic.vhd | 79 +-- cores/c16/c16_mist.qsf | 18 +- 15 files changed, 2105 insertions(+), 62 deletions(-) create mode 100644 cores/c16/1541ultimate2cpu/alu.vhd create mode 100644 cores/c16/1541ultimate2cpu/bit_cpx_cpy.vhd create mode 100644 cores/c16/1541ultimate2cpu/cpu6502.vhd create mode 100644 cores/c16/1541ultimate2cpu/data_oper.vhd create mode 100644 cores/c16/1541ultimate2cpu/implied.vhd create mode 100644 cores/c16/1541ultimate2cpu/pkg_6502_decode.vhd create mode 100644 cores/c16/1541ultimate2cpu/pkg_6502_defs.vhd create mode 100644 cores/c16/1541ultimate2cpu/pkg_6502_opcodes.vhd create mode 100644 cores/c16/1541ultimate2cpu/proc_control.vhd create mode 100644 cores/c16/1541ultimate2cpu/proc_core.vhd create mode 100644 cores/c16/1541ultimate2cpu/proc_interrupt.vhd create mode 100644 cores/c16/1541ultimate2cpu/proc_registers.vhd create mode 100644 cores/c16/1541ultimate2cpu/shifter.vhd diff --git a/cores/c16/1541ultimate2cpu/alu.vhd b/cores/c16/1541ultimate2cpu/alu.vhd new file mode 100644 index 0000000..b5d35dc --- /dev/null +++ b/cores/c16/1541ultimate2cpu/alu.vhd @@ -0,0 +1,137 @@ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; + +entity alu is +generic ( + support_bcd : boolean := true ); +port ( + operation : in std_logic_vector(2 downto 0); + enable : in std_logic; + + n_in : in std_logic; + v_in : in std_logic; + z_in : in std_logic; + c_in : in std_logic; + d_in : in std_logic; + + data_a : in std_logic_vector(7 downto 0); + data_b : in std_logic_vector(7 downto 0); + + n_out : out std_logic; + v_out : out std_logic; + z_out : out std_logic; + c_out : out std_logic; + + data_out : out std_logic_vector(7 downto 0)); + +end alu; + +architecture gideon of alu is + signal data_out_i : std_logic_vector(7 downto 0) := X"FF"; + signal zero : std_logic; + signal sum_c : std_logic; + signal sum_n : std_logic; + signal sum_z : std_logic; + signal sum_v : std_logic; + signal sum_result : std_logic_vector(7 downto 0) := X"FF"; + signal oper4 : std_logic_vector(3 downto 0); +begin + +-- ORA $nn AND $nn EOR $nn ADC $nn STA $nn LDA $nn CMP $nn SBC $nn + + with oper4 select data_out_i <= + data_a or data_b when "1000", + data_a and data_b when "1001", + data_a xor data_b when "1010", + sum_result when "1011" | "1110" | "1111", + data_b when others; + + zero <= '1' when data_out_i = X"00" else '0'; + + sum: process(data_a, data_b, c_in, operation, d_in) + variable b : std_logic_vector(7 downto 0); + variable sum_l : std_logic_vector(4 downto 0); + variable sum_h : std_logic_vector(4 downto 0); + begin + -- for subtraction invert second operand + if operation(2)='1' then -- invert b + b := not data_b; + else + b := data_b; + end if; + + -- sum_l(4) = carry of lower end, carry in is masked to '1' for CMP + sum_l := ('0' & data_a(3 downto 0)) + ('0' & b(3 downto 0)) + (c_in or not operation(0)); + sum_h := ('0' & data_a(7 downto 4)) + ('0' & b(7 downto 4)) + sum_l(4); + + if sum_l(3 downto 0)="0000" and sum_h(3 downto 0)="0000" then + sum_z <= '1'; + else + sum_z <= '0'; + end if; + + sum_n <= sum_h(3); + sum_c <= sum_h(4); + sum_v <= (sum_h(3) xor data_a(7)) and (sum_h(3) xor data_b(7) xor operation(2)); + + -- fix up in decimal mode (not for CMP!) + if d_in='1' and support_bcd then + if operation(2)='0' then -- ADC + sum_h := ('0' & data_a(7 downto 4)) + ('0' & b(7 downto 4)); + + if sum_l(4) = '1' or sum_l(3 downto 2)="11" or sum_l(3 downto 1)="101" then -- >9 (10-11, 12-15) + sum_l := sum_l + ('0' & X"6"); + sum_l(4) := '1'; + end if; + + -- negative when sum_h + sum_l(4) = 8 + sum_h := sum_h + sum_l(4); + sum_n <= sum_h(3); + + if sum_h(4) = '1' or sum_h(3 downto 2)="11" or sum_h(3 downto 1)="101" then -- + sum_h := sum_h + 6; + sum_c <= '1'; + end if; + + -- carry and overflow are output after fix +-- sum_c <= sum_h(4); +-- sum_v <= (sum_h(3) xor data_a(7)) and (sum_h(3) xor data_b(7) xor operation(2)); + + elsif operation(0)='1' then -- SBC + -- flags are not adjusted in subtract mode + if sum_l(4) = '0' then + sum_l := sum_l - 6; + end if; + if sum_h(4) = '0' then + sum_h := sum_h - 6; + end if; + end if; + end if; + + sum_result <= sum_h(3 downto 0) & sum_l(3 downto 0); + end process; + + oper4 <= enable & operation; + + with oper4 select c_out <= + sum_c when "1011" | "1111" | "1110", + c_in when others; + + with oper4 select z_out <= + sum_z when "1011" | "1111" | "1110", + zero when "1000" | "1001" | "1010" | "1101", + z_in when others; + + with oper4 select n_out <= + sum_n when "1011" | "1111", + data_out_i(7) when "1000" | "1001" | "1010" | "1101" | "1110", + n_in when others; + + with oper4 select v_out <= + sum_v when "1011" | "1111", + v_in when others; + + data_out <= data_out_i; +end gideon; \ No newline at end of file diff --git a/cores/c16/1541ultimate2cpu/bit_cpx_cpy.vhd b/cores/c16/1541ultimate2cpu/bit_cpx_cpy.vhd new file mode 100644 index 0000000..36def28 --- /dev/null +++ b/cores/c16/1541ultimate2cpu/bit_cpx_cpy.vhd @@ -0,0 +1,66 @@ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; + +entity bit_cpx_cpy is +port ( + operation : in std_logic_vector(2 downto 0); + enable : in std_logic := '1'; -- instruction(1 downto 0)="00" + + n_in : in std_logic; + v_in : in std_logic; + z_in : in std_logic; + c_in : in std_logic; + + data_in : in std_logic_vector(7 downto 0); + a_reg : in std_logic_vector(7 downto 0); + x_reg : in std_logic_vector(7 downto 0); + y_reg : in std_logic_vector(7 downto 0); + + n_out : out std_logic; + v_out : out std_logic; + z_out : out std_logic; + c_out : out std_logic ); + +end bit_cpx_cpy; + +architecture gideon of bit_cpx_cpy is + signal reg : std_logic_vector(7 downto 0) := (others => '0'); + signal diff : std_logic_vector(8 downto 0) := (others => '0'); + signal zero_cmp : std_logic; + signal zero_ld : std_logic; + signal zero_bit : std_logic; + + signal oper4 : std_logic_vector(3 downto 0); +begin +-- *** BIT *** *** STY LDY CPY CPX + reg <= x_reg when operation(0)='1' else y_reg; + + diff <= ('1' & reg) - ('0' & data_in); + zero_cmp <= '1' when diff(7 downto 0)=X"00" else '0'; + zero_ld <= '1' when data_in=X"00" else '0'; + zero_bit <= '1' when (data_in and a_reg)=X"00" else '0'; + + oper4 <= enable & operation; + + with oper4 select c_out <= + diff(8) when "1110" | "1111", -- CPX / CPY + c_in when others; + + with oper4 select z_out <= + zero_cmp when "1110" | "1111", -- CPX / CPY + zero_ld when "1101", + zero_bit when "1001", + z_in when others; + + with oper4 select n_out <= + diff(7) when "1110" | "1111", -- CPX / CPY + data_in(7) when "1101" | "1001", -- LDY / BIT + n_in when others; + + with oper4 select v_out <= + data_in(6) when "1001", -- BIT + v_in when others; + +end gideon; diff --git a/cores/c16/1541ultimate2cpu/cpu6502.vhd b/cores/c16/1541ultimate2cpu/cpu6502.vhd new file mode 100644 index 0000000..9ba5e39 --- /dev/null +++ b/cores/c16/1541ultimate2cpu/cpu6502.vhd @@ -0,0 +1,55 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; + +entity cpu6502 is +port ( + cpu_clk : in std_logic; + cpu_reset : in std_logic; + + cpu_ready : in std_logic; + cpu_write : out std_logic; + + cpu_wdata : out std_logic_vector(7 downto 0); + cpu_rdata : in std_logic_vector(7 downto 0); + cpu_addr : out std_logic_vector(16 downto 0); + cpu_pc : out std_logic_vector(15 downto 0); + + IRQn : in std_logic; -- IRQ interrupt (level sensitive) + NMIn : in std_logic; -- NMI interrupt (edge sensitive) + + SOn : in std_logic -- set Overflow flag +); + attribute optimize : string; + attribute optimize of cpu6502 : entity is "SPEED"; +end cpu6502; + + + +architecture cycle_exact of cpu6502 is + + signal read_write_n : std_logic; + +begin + + core: entity work.proc_core + generic map ( + support_bcd => true ) + port map( + clock => cpu_clk, + clock_en => cpu_ready, + reset => cpu_reset, + + irq_n => IRQn, + nmi_n => NMIn, + so_n => SOn, + + pc_out => cpu_pc, + addr_out => cpu_addr, + data_in => cpu_rdata, + data_out => cpu_wdata, + read_write_n => read_write_n ); + + cpu_write <= not read_write_n; + +end cycle_exact; diff --git a/cores/c16/1541ultimate2cpu/data_oper.vhd b/cores/c16/1541ultimate2cpu/data_oper.vhd new file mode 100644 index 0000000..eca1911 --- /dev/null +++ b/cores/c16/1541ultimate2cpu/data_oper.vhd @@ -0,0 +1,193 @@ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; + +library work; +use work.pkg_6502_decode.all; + +-- this module puts the alu, shifter and bit/compare unit together + +entity data_oper is +generic ( + support_bcd : boolean := true ); +port ( + inst : in std_logic_vector(7 downto 0); + + n_in : in std_logic; + v_in : in std_logic; + z_in : in std_logic; + c_in : in std_logic; + d_in : in std_logic; + i_in : in std_logic; + + data_in : in std_logic_vector(7 downto 0); + a_reg : in std_logic_vector(7 downto 0); + x_reg : in std_logic_vector(7 downto 0); + y_reg : in std_logic_vector(7 downto 0); + s_reg : in std_logic_vector(7 downto 0); + + alu_out : out std_logic_vector(7 downto 0); + mem_out : out std_logic_vector(7 downto 0); + impl_out : out std_logic_vector(7 downto 0); + + set_a : out std_logic; + set_x : out std_logic; + set_y : out std_logic; + set_s : out std_logic; + + n_out : out std_logic; + v_out : out std_logic; + z_out : out std_logic; + c_out : out std_logic; + d_out : out std_logic; + i_out : out std_logic ); +end data_oper; + +architecture gideon of data_oper is + signal shift_sel : std_logic_vector(1 downto 0) := "00"; + signal shift_din : std_logic_vector(7 downto 0) := X"00"; + signal shift_dout: std_logic_vector(7 downto 0) := X"00"; + signal alu_data_a: std_logic_vector(7 downto 0) := X"00"; + signal row0_n : std_logic; + signal row0_v : std_logic; + signal row0_z : std_logic; + signal row0_c : std_logic; + + signal shft_n : std_logic; + signal shft_z : std_logic; + signal shft_c : std_logic; + + signal alu_n : std_logic; + signal alu_v : std_logic; + signal alu_z : std_logic; + signal alu_c : std_logic; + + signal impl_n : std_logic; + signal impl_z : std_logic; + signal impl_c : std_logic; + signal impl_v : std_logic; + signal impl_i : std_logic; + signal impl_d : std_logic; + + signal shift_en : std_logic; + signal alu_en : std_logic; + signal impl_en : std_logic; + signal impl_flags: boolean; +begin + shift_sel <= shifter_in_select(inst); + with shift_sel select shift_din <= + data_in when "01", + a_reg when "10", + data_in and a_reg when "11", + X"FF" when others; + + shift_en <= '1' when is_shift(inst) else '0'; + alu_en <= '1' when is_alu(inst) else '0'; + + row0: entity work.bit_cpx_cpy + port map ( + operation => inst(7 downto 5), + enable => '1', + + n_in => n_in, + v_in => v_in, + z_in => z_in, + c_in => c_in, + + data_in => data_in, + a_reg => a_reg, + x_reg => x_reg, + y_reg => y_reg, + + n_out => row0_n, + v_out => row0_v, + z_out => row0_z, + c_out => row0_c ); + + shft: entity work.shifter + port map ( + operation => inst(7 downto 5), + enable => shift_en, + + c_in => c_in, + n_in => n_in, + z_in => z_in, + + data_in => shift_din, + + c_out => shft_c, + n_out => shft_n, + z_out => shft_z, + + data_out => shift_dout ); + + alu_data_a <= a_reg and x_reg when x_to_alu(inst) else a_reg; + + alu1: entity work.alu + generic map ( + support_bcd => support_bcd ) + port map ( + operation => inst(7 downto 5), + enable => alu_en, + + n_in => shft_n, + v_in => v_in, + z_in => shft_z, + c_in => shft_c, + d_in => d_in, + + data_a => alu_data_a, + data_b => shift_dout, + + n_out => alu_n, + v_out => alu_v, + z_out => alu_z, + c_out => alu_c, + + data_out => alu_out ); + + mem_out <= shift_dout; + + impl_en <= '1' when is_implied(inst) else '0'; + impl_flags <= is_implied(inst) and (inst(4)='1' or inst(7)='1'); + + impl: entity work.implied + port map ( + inst => inst, + enable => impl_en, + + c_in => c_in, + i_in => i_in, + n_in => n_in, + z_in => z_in, + d_in => d_in, + v_in => v_in, + + reg_a => a_reg, + reg_x => x_reg, + reg_y => y_reg, + reg_s => s_reg, + + i_out => impl_i, + d_out => impl_d, + c_out => impl_c, + n_out => impl_n, + z_out => impl_z, + v_out => impl_v, + + set_a => set_a, + set_x => set_x, + set_y => set_y, + set_s => set_s, + + data_out => impl_out ); + + n_out <= impl_n when impl_flags else row0_n when inst(1 downto 0)="00" else alu_n; + v_out <= impl_v when impl_flags else row0_v when inst(1 downto 0)="00" else alu_v; + z_out <= impl_z when impl_flags else row0_z when inst(1 downto 0)="00" else alu_z; + c_out <= impl_c when impl_flags else row0_c when inst(1 downto 0)="00" else alu_c; + i_out <= impl_i when impl_flags else i_in; + d_out <= impl_d when impl_flags else d_in; + +end gideon; diff --git a/cores/c16/1541ultimate2cpu/implied.vhd b/cores/c16/1541ultimate2cpu/implied.vhd new file mode 100644 index 0000000..bfdeaa4 --- /dev/null +++ b/cores/c16/1541ultimate2cpu/implied.vhd @@ -0,0 +1,114 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; + +entity implied is +port ( + inst : in std_logic_vector(7 downto 0); + enable : in std_logic; + + c_in : in std_logic; + i_in : in std_logic; + n_in : in std_logic; + z_in : in std_logic; + d_in : in std_logic; + v_in : in std_logic; + + reg_a : in std_logic_vector(7 downto 0); + reg_x : in std_logic_vector(7 downto 0); + reg_y : in std_logic_vector(7 downto 0); + reg_s : in std_logic_vector(7 downto 0); + + c_out : out std_logic; + i_out : out std_logic; + n_out : out std_logic; + z_out : out std_logic; + d_out : out std_logic; + v_out : out std_logic; + + set_a : out std_logic; + set_x : out std_logic; + set_y : out std_logic; + set_s : out std_logic; + + data_out : out std_logic_vector(7 downto 0)); + +end implied; + +architecture gideon of implied is + type t_int4_array is array(natural range <>) of integer range 0 to 3; + -- ROMS for the upper (negative) implied instructions + constant reg_sel_rom : t_int4_array(0 to 15) := ( 2,0,2,1,1,0,1,1,2,0,2,1,1,3,1,1 ); -- 0=A, 1=X, 2=Y, 3=S + constant decr_rom : std_logic_vector(0 to 15) := "1000001000000000"; + constant incr_rom : std_logic_vector(0 to 15) := "0011000000000000"; + constant nz_flags : std_logic_vector(0 to 15) := "1111111010000100"; + constant v_flag : std_logic_vector(0 to 15) := "0000000001000000"; + constant d_flag : std_logic_vector(0 to 15) := "0000000000110000"; + constant set_a_rom : std_logic_vector(0 to 15) := "0000100010000000"; + constant set_x_rom : std_logic_vector(0 to 15) := "0001011000000100"; + constant set_y_rom : std_logic_vector(0 to 15) := "1110000000000000"; + constant set_s_rom : std_logic_vector(0 to 15) := "0000000000001000"; + + -- ROMS for the lower (positive) implied instructions + constant shft_rom : std_logic_vector(0 to 15) := "0000111100000000"; + constant c_flag : std_logic_vector(0 to 15) := "0000000011000000"; + constant i_flag : std_logic_vector(0 to 15) := "0000000000110000"; + + signal selected_reg : std_logic_vector(7 downto 0) := X"00"; + signal operation : integer range 0 to 15; + signal reg_sel : integer range 0 to 3; + signal result : std_logic_vector(7 downto 0) := X"00"; + signal add : std_logic_vector(7 downto 0) := X"00"; + signal carry : std_logic := '0'; + signal zero : std_logic := '0'; + + signal n_hi : std_logic; + signal z_hi : std_logic; + signal v_hi : std_logic; + signal d_hi : std_logic; + + signal n_lo : std_logic; + signal z_lo : std_logic; + signal c_lo : std_logic; + signal i_lo : std_logic; +begin + operation <= conv_integer(inst(4) & inst(1) & inst(6 downto 5)); + reg_sel <= reg_sel_rom(operation); + with reg_sel select selected_reg <= + reg_a when 0, + reg_x when 1, + reg_y when 2, + reg_s when others; + + add <= (others => decr_rom(operation)); + carry <= incr_rom(operation); + + result <= selected_reg + add + carry; + + zero <= '1' when result = X"00" else '0'; + + data_out <= result; + + n_hi <= result(7) when nz_flags(operation)='1' else n_in; + z_hi <= zero when nz_flags(operation)='1' else z_in; + v_hi <= '0' when v_flag(operation)='1' else v_in; + d_hi <= inst(5) when d_flag(operation)='1' else d_in; + -- in high, C and I are never set + + c_lo <= inst(5) when c_flag(operation)='1' else c_in; + i_lo <= inst(5) when i_flag(operation)='1' else i_in; + -- in low, V, N, Z and D are never set + + set_a <= set_a_rom(operation) and inst(7) and enable; + set_x <= set_x_rom(operation) and inst(7) and enable; + set_y <= set_y_rom(operation) and inst(7) and enable; + set_s <= set_s_rom(operation) and inst(7) and enable; + + c_out <= c_in when inst(7)='1' else c_lo; -- C can only be set in lo + i_out <= i_in when inst(7)='1' else i_lo; -- I can only be set in lo + v_out <= v_hi when inst(7)='1' else v_in; -- V can only be set in hi + d_out <= d_hi when inst(7)='1' else d_in; -- D can only be set in hi + n_out <= n_hi when inst(7)='1' else n_in; -- N can only be set in hi + z_out <= z_hi when inst(7)='1' else z_in; -- Z can only be set in hi + +end gideon; \ No newline at end of file diff --git a/cores/c16/1541ultimate2cpu/pkg_6502_decode.vhd b/cores/c16/1541ultimate2cpu/pkg_6502_decode.vhd new file mode 100644 index 0000000..2b7af5a --- /dev/null +++ b/cores/c16/1541ultimate2cpu/pkg_6502_decode.vhd @@ -0,0 +1,248 @@ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; + +package pkg_6502_decode is + + function is_absolute(inst: std_logic_vector(7 downto 0)) return boolean; + function is_abs_jump(inst: std_logic_vector(7 downto 0)) return boolean; + function is_immediate(inst: std_logic_vector(7 downto 0)) return boolean; + function is_implied(inst: std_logic_vector(7 downto 0)) return boolean; + function is_stack(inst: std_logic_vector(7 downto 0)) return boolean; + function is_push(inst: std_logic_vector(7 downto 0)) return boolean; + function is_zeropage(inst: std_logic_vector(7 downto 0)) return boolean; + function is_indirect(inst: std_logic_vector(7 downto 0)) return boolean; + function is_relative(inst: std_logic_vector(7 downto 0)) return boolean; + function is_load(inst: std_logic_vector(7 downto 0)) return boolean; + function is_store(inst: std_logic_vector(7 downto 0)) return boolean; + function is_shift(inst: std_logic_vector(7 downto 0)) return boolean; + function is_alu(inst: std_logic_vector(7 downto 0)) return boolean; + function is_rmw(inst: std_logic_vector(7 downto 0)) return boolean; + function is_jump(inst: std_logic_vector(7 downto 0)) return boolean; + function is_postindexed(inst: std_logic_vector(7 downto 0)) return boolean; + function is_illegal(inst: std_logic_vector(7 downto 0)) return boolean; + + function stack_idx(inst: std_logic_vector(7 downto 0)) return std_logic_vector; + + constant c_stack_idx_brk : std_logic_vector(1 downto 0) := "00"; + constant c_stack_idx_jsr : std_logic_vector(1 downto 0) := "01"; + constant c_stack_idx_rti : std_logic_vector(1 downto 0) := "10"; + constant c_stack_idx_rts : std_logic_vector(1 downto 0) := "11"; + + function select_index_y (inst: std_logic_vector(7 downto 0)) return boolean; + function store_a_from_alu (inst: std_logic_vector(7 downto 0)) return boolean; + function load_a (inst: std_logic_vector(7 downto 0)) return boolean; + function load_x (inst: std_logic_vector(7 downto 0)) return boolean; + function load_y (inst: std_logic_vector(7 downto 0)) return boolean; + function shifter_in_select (inst: std_logic_vector(7 downto 0)) return std_logic_vector; + function x_to_alu (inst: std_logic_vector(7 downto 0)) return boolean; +end; + +package body pkg_6502_decode is + + function is_absolute(inst: std_logic_vector(7 downto 0)) return boolean is + begin + -- 4320 = X11X | 1101 + if inst(3 downto 2)="11" then + return true; + elsif inst(4 downto 2)="110" and inst(0)='1' then + return true; + end if; + return false; + end function; + + function is_jump(inst: std_logic_vector(7 downto 0)) return boolean is + begin + return inst(7 downto 6)="01" and inst(3 downto 0)=X"C"; + end function; + + function is_immediate(inst: std_logic_vector(7 downto 0)) return boolean is + begin + -- 76543210 = 1XX000X0 + if inst(7)='1' and inst(4 downto 2)="000" and inst(0)='0' then + return true; + -- 76543210 = XXX010X1 + elsif inst(4 downto 2)="010" and inst(0)='1' then + return true; + end if; + return false; + end function; + + function is_implied(inst: std_logic_vector(7 downto 0)) return boolean is + begin + -- 4320 = X100 + return inst(3 downto 2)="10" and inst(0)='0'; + end function; + + function is_stack(inst: std_logic_vector(7 downto 0)) return boolean is + begin + -- 76543210 + -- 0xx0x000 + return inst(7)='0' and inst(4)='0' and inst(2 downto 0)="000"; + end function; + + function is_push(inst: std_logic_vector(7 downto 0)) return boolean is + begin + -- we already know it's a stack operation, so only the direction is important + return inst(5)='0'; + end function; + + function is_zeropage(inst: std_logic_vector(7 downto 0)) return boolean is + begin + if inst(3 downto 2)="01" then + return true; + elsif inst(3 downto 2)="00" and inst(0)='1' then + return true; + end if; + return false; + end function; + + function is_indirect(inst: std_logic_vector(7 downto 0)) return boolean is + begin + return (inst(3 downto 2)="00" and inst(0)='1'); + end function; + + function is_relative(inst: std_logic_vector(7 downto 0)) return boolean is + begin + return (inst(4 downto 0)="10000"); + end function; + + function is_store(inst: std_logic_vector(7 downto 0)) return boolean is + begin + return (inst(7 downto 5)="100"); + end function; + + function is_shift(inst: std_logic_vector(7 downto 0)) return boolean is + begin + if inst(7)='1' and inst(4 downto 2)="010" then + return false; + end if; + return (inst(1)='1'); + end function; + + function is_alu(inst: std_logic_vector(7 downto 0)) return boolean is + begin + if inst(7)='0' and inst(4 downto 1)="0101" then + return false; + end if; + return (inst(0)='1'); + end function; + + function is_load(inst: std_logic_vector(7 downto 0)) return boolean is + begin + return not is_store(inst) and not is_rmw(inst); + end function; + + function is_rmw(inst: std_logic_vector(7 downto 0)) return boolean is + begin + return inst(1)='1' and inst(7 downto 6)/="10"; + end function; + + function is_abs_jump(inst: std_logic_vector(7 downto 0)) return boolean is + begin + return is_jump(inst) and inst(5)='0'; + end function; + + function is_postindexed(inst: std_logic_vector(7 downto 0)) return boolean is + begin + return inst(4)='1'; + end function; + + function stack_idx(inst: std_logic_vector(7 downto 0)) return std_logic_vector is + begin + return inst(6 downto 5); + end function; + + function select_index_y (inst: std_logic_vector(7 downto 0)) return boolean is + begin + if inst(4)='1' and inst(2)='0' and inst(0)='1' then -- XXX1X0X1 + return true; + elsif inst(7 downto 6)="10" and inst(2 downto 1)="11" then -- 10XXX11X + return true; + end if; + return false; + end function; + +-- function flags_bit_group (inst: std_logic_vector(7 downto 0)) return boolean is +-- begin +-- return inst(2 downto 0)="100"; +-- end function; +-- +-- function flags_alu_group (inst: std_logic_vector(7 downto 0)) return boolean is +-- begin +-- return inst(1 downto 0)="01"; -- could also choose not to look at bit 1 (overlap) +-- end function; +-- +-- function flags_shift_group (inst: std_logic_vector(7 downto 0)) return boolean is +-- begin +-- return inst(1 downto 0)="10"; -- could also choose not to look at bit 0 (overlap) +-- end function; + + function load_a (inst: std_logic_vector(7 downto 0)) return boolean is + begin + return (inst = X"68"); + end function; + + function store_a_from_alu (inst: std_logic_vector(7 downto 0)) return boolean is + begin + -- 0XXXXXX1 or alu operations "lo" + -- 1X100001 or alu operations "hi" (except store and cmp) + -- 0XX01010 (implied) + return (inst(7)='0' and inst(4 downto 0)="01010") or + (inst(7)='0' and inst(0)='1') or + (inst(7)='1' and inst(0)='1' and inst(5)='1'); + end function; + + function load_x (inst: std_logic_vector(7 downto 0)) return boolean is + begin + -- 101XXX1X or 1100101- (for SAX #) + if inst(7 downto 1)="1100101" then + return true; + end if; + return inst(7 downto 5)="101" and inst(1)='1' and not is_implied(inst); + end function; + + function load_y (inst: std_logic_vector(7 downto 0)) return boolean is + begin + -- 101XXX00 + return inst(7 downto 5)="101" and inst(1 downto 0)="00" and not is_implied(inst); + end function; + + function shifter_in_select (inst: std_logic_vector(7 downto 0)) return std_logic_vector is + begin + -- 00 = none, 01 = memory, 10 = A, 11 = A & M + if inst(4 downto 2)="010" and inst(7)='0' then + return inst(1 downto 0); + end if; + return "01"; + end function; + +-- function shifter_in_select (inst: std_logic_vector(7 downto 0)) return std_logic_vector is +-- begin +-- -- 0=memory, 1=A +-- if inst(4 downto 1)="0101" and inst(7)='0' then +-- return "01"; +-- end if; +-- return "10"; +-- end function; + + function is_illegal (inst: std_logic_vector(7 downto 0)) return boolean is + type t_my16bit_array is array(natural range <>) of std_logic_vector(15 downto 0); + constant c_illegal_map : t_my16bit_array(0 to 15) := ( + X"989C", X"9C9C", X"888C", X"9C9C", X"889C", X"9C9C", X"889C", X"9C9C", + X"8A8D", X"D88C", X"8888", X"888C", X"888C", X"9C9C", X"888C", X"9C9C" ); + variable row : std_logic_vector(15 downto 0); + begin + row := c_illegal_map(conv_integer(inst(7 downto 4))); + return (row(conv_integer(inst(3 downto 0))) = '1'); + end function; + + function x_to_alu (inst: std_logic_vector(7 downto 0)) return boolean is + begin + -- 1-00101- 8A,8B,CA,CB + return inst(5 downto 1)="00101" and inst(7)='1'; + end function; + +end; diff --git a/cores/c16/1541ultimate2cpu/pkg_6502_defs.vhd b/cores/c16/1541ultimate2cpu/pkg_6502_defs.vhd new file mode 100644 index 0000000..808429c --- /dev/null +++ b/cores/c16/1541ultimate2cpu/pkg_6502_defs.vhd @@ -0,0 +1,18 @@ + +library ieee; +use ieee.std_logic_1164.all; + +package pkg_6502_defs is + + subtype t_amux is integer range 0 to 3; + constant c_amux_vector : t_amux := 0; + constant c_amux_addr : t_amux := 1; + constant c_amux_stack : t_amux := 2; + constant c_amux_pc : t_amux := 3; + + type t_pc_oper is (keep, increment, copy, from_alu); + type t_adl_oper is (keep, increment, add_idx, load_bus, copy_dreg); + type t_adh_oper is (keep, increment, clear, load_bus); + type t_sp_oper is (keep, increment, decrement); + type t_dout_mux is (reg_d, reg_accu, reg_axy, reg_flags, reg_pcl, reg_pch, shift_res); +end; diff --git a/cores/c16/1541ultimate2cpu/pkg_6502_opcodes.vhd b/cores/c16/1541ultimate2cpu/pkg_6502_opcodes.vhd new file mode 100644 index 0000000..1e04749 --- /dev/null +++ b/cores/c16/1541ultimate2cpu/pkg_6502_opcodes.vhd @@ -0,0 +1,88 @@ + +package pkg_6502_opcodes is + +type t_opcode_array is array(0 to 255) of string(1 to 13); + +constant opcode_array : t_opcode_array := ( + + "BRK ", "ORA ($nn,X) ", "HLT* ", "ASO*($nn,X) ", + "BOT*$nn ", "ORA $nn ", "ASL $nn ", "ASO*$nn ", + "PHP ", "ORA # ", "ASL A ", "ORA*# ", + "BOT*$nnnnn ", "ORA $nnnn ", "ASL $nnnn ", "ASO*$nnnn ", + + "BPL rel ", "ORA ($nn),Y ", "HLT* ", "ASO*($nn),Y ", + "BOT*$nn,X ", "ORA $nn,X ", "ASL $nn,X ", "ASO*$nn,X ", + "CLC ", "ORA $nnnn,Y ", "NOP* ", "ASO*$nnnn,Y ", + "BOT*$nnnn,X ", "ORA $nnnn,X ", "ASL $nnnn,X ", "ASO*$nnnn,X ", + + "JSR $nnnn ", "AND ($nn,X) ", "HLT* ", "RLA*($nn,X) ", + "BIT $nn ", "AND $nn ", "ROL $nn ", "RLA*$nn ", + "PLP ", "AND # ", "ROL A ", "AND*# ", + "BIT $nnnn ", "AND $nnnn ", "ROL $nnnn ", "RLA*$nnnn ", + + "BMI rel ", "AND ($nn),Y ", "HLT* ", "RLA*($nn),Y ", + "BIT*$nn,X ", "AND $nn,X ", "ROL $nn,X ", "RLA*$nn,X ", + "SEC ", "AND $nnnn,Y ", "NOP* ", "RLA*$nnnn,Y ", + "BIT*$nnnn,X ", "AND $nnnn,X ", "ROL $nnnn,X ", "RLA*$nnnn,X ", + + "RTI ", "EOR ($nn,X) ", "HLT* ", "LSE*($nn,X) ", + "RDM* ", "EOR $nn ", "LSR $nn ", "LSE*$nn ", + "PHA ", "EOR # ", "LSR A ", "EOR*# ", + "JMP $nnnn ", "EOR $nnnn ", "LSR $nnnn ", "LSE*$nnnn ", + + "BVC rel ", "EOR ($nn),Y ", "HLT* ", "LSE*($nn),Y ", + "RDM* ", "EOR $nn,X ", "LSR $nn,X ", "LSE*$nn,X ", + "CLI ", "EOR $nnnn,Y ", "NOP* ", "LSE*$nnnn,Y ", + "JMP*$nnnn ", "EOR $nnnn,X ", "LSR $nnnn,X ", "LSE*$nnnn,X ", + + "RTS ", "ADC ($nn,X) ", "HLT* ", "RRA*($nn,X) ", + "RDM* ", "ADC $nn ", "ROR $nn ", "RRA*$nn ", + "PLA ", "ADC # ", "ROR A ", "ADC*# ", + "JMP ($nnnn) ", "ADC $nnnn ", "ROR $nnnn ", "RRA*$nnnn ", + + "BVS rel ", "ADC ($nn),Y ", "HLT* ", "RRA*($nn),Y ", + "RDM* ", "ADC $nn,X ", "ROR $nn,X ", "RRA*$nn,X ", + "SEI ", "ADC $nnnn,Y ", "NOP* ", "RRA*$nnnn,Y ", + "JMP*($nnnn,X)", "ADC $nnnn,X ", "ROR $nnnn,X ", "RRA*$nnnn,X ", + + "SKB* ", "STA ($nn,X) ", "SKB* ", "AXS*($nn,X) ", + "STY $nn ", "STA $nn ", "STX $nn ", "AXS*$nn ", + "DEY ", "SKB* ", "TXA ", "???* ", + "STY $nnnn ", "STA $nnnn ", "STX $nnnn ", "AXS*$nnnn ", + + "BCC ", "STA ($nn),Y ", "HLT* ", "AXS*($nn),Y ", + "STY $nn,X ", "STA $nn,X ", "STX $nn,Y ", "AXS*$nn,Y ", + "TYA ", "STA $nnnn,Y ", "TXS ", "AXS*$nnnn,Y ", + "STY*$nnnn,X ", "STA $nnnn,X ", "STX*$nnnn,Y ", "AXS*$nnnn,Y ", + + "LDY # ", "LDA ($nn,X) ", "LDX # ", "LAX*($nn,X) ", + "LDY $nn ", "LDA $nn ", "LDX $nn ", "LAX*$nn ", + "TAY ", "LDA # ", "TAX ", "LAX*# ", + "LDY $nnnn ", "LDA $nnnn ", "LDX $nnnn ", "LAX*$nnnn ", + + "BCS ", "LDA ($nn),Y ", "HLT* ", "LAX*($nn),Y ", + "LDY $nn,X ", "LDA $nn,X ", "LDX $nn,Y ", "LAX*$nn,Y ", + "CLV ", "LDA $nnnn,Y ", "TSX ", "LAX*$nnnn,Y ", + "LDY $nnnn,X ", "LDA $nnnn,X ", "LDX $nnnn,Y ", "LAX*$nnnn,Y ", + + "CPY # ", "CMP ($nn,X) ", "SKB* ", "DCM*($nn,X) ", + "CPY $nn ", "CMP $nn ", "DEC $nn ", "DCM*$nn ", + "INY ", "CMP # ", "DEX ", "SAX*# (used!)", + "CPY $nnnn ", "CMP $nnnn ", "DEC $nnnn ", "DCM*$nnnn ", + + "BNE ", "CMP ($nn),Y ", "HLT* ", "DCM*($nn),Y ", + "RDM* ", "CMP $nn,X ", "DEC $nn,X ", "DCM*$nn,X ", + "CLD ", "CMP $nnnn,Y ", "NOP* ", "DCM*$nnnn,Y ", + "RDM*$nnnn,X ", "CMP $nnnn,X ", "DEC $nnnn,X ", "DCM*$nnnn,X ", + + "CPX # ", "SBC ($nn,X) ", "SKB* ", "INS*($nn,X) ", + "CPX $nn ", "SBC $nn ", "INC $nn ", "INS*$nn ", + "INX ", "SBC # ", "NOP ", "SBC*# ", + "CPX $nnnn ", "SBC $nnnn ", "INC $nnnn ", "INS*$nnnn ", + + "BEQ ", "SBC ($nn),Y ", "HLT* ", "INS*($nn),Y ", + "RDM* ", "SBC $nn,X ", "INC $nn,X ", "INS*$nn,X ", + "SED ", "SBC $nnnn,Y ", "NOP* ", "INS*$nnnn,Y ", + "RDM*$nnnn,X ", "SBC $nnnn,X ", "INC $nnnn,X ", "INS*$nnnn,X " ); + +end; diff --git a/cores/c16/1541ultimate2cpu/proc_control.vhd b/cores/c16/1541ultimate2cpu/proc_control.vhd new file mode 100644 index 0000000..db56a2b --- /dev/null +++ b/cores/c16/1541ultimate2cpu/proc_control.vhd @@ -0,0 +1,472 @@ + +library ieee; +use ieee.std_logic_1164.all; + +library work; +use work.pkg_6502_defs.all; +use work.pkg_6502_decode.all; + +entity proc_control is +port ( + clock : in std_logic; + clock_en : in std_logic; + reset : in std_logic; + + interrupt : in std_logic; + i_reg : in std_logic_vector(7 downto 0); + index_carry : in std_logic; + pc_carry : in std_logic; + branch_taken : in boolean; + + sync : out std_logic; + dummy_cycle : out std_logic; + set_b : out std_logic; + latch_dreg : out std_logic; + copy_d2p : out std_logic; + reg_update : out std_logic; + rwn : out std_logic; + vect_bit : out std_logic := '0'; + a16 : out std_logic; + a_mux : out t_amux := c_amux_pc; + dout_mux : out t_dout_mux; + pc_oper : out t_pc_oper; + s_oper : out t_sp_oper; + adl_oper : out t_adl_oper; + adh_oper : out t_adh_oper ); + +end proc_control; + + +architecture gideon of proc_control is + + type t_state is (fetch, decode, absolute, abs_hi, abs_fix, branch, branch_fix, + indir1, indir2, jump_sub, jump, retrn, rmw1, rmw2, vector, startup, + zp, zp_idx, zp_indir, push1, push2, push3, pull1, pull2, pull3 ); + + signal state : t_state; + signal next_state : t_state; + + signal next_cp_p : std_logic; + signal next_rwn : std_logic; + signal next_dreg : std_logic; + signal next_amux : t_amux; + signal next_dout : t_dout_mux; + signal next_set_b : std_logic; + signal next_dummy : std_logic; + signal vectoring : std_logic; +begin + -- combinatroial process + process(state, i_reg, index_carry, pc_carry, branch_taken, interrupt, vectoring) + variable v_stack_idx : std_logic_vector(1 downto 0); + begin + -- defaults + sync <= '0'; + pc_oper <= increment; + next_amux <= c_amux_pc; + next_rwn <= '1'; + next_state <= state; + adl_oper <= keep; + adh_oper <= keep; + s_oper <= keep; + next_dreg <= '1'; + next_cp_p <= '0'; + next_dout <= reg_d; + next_set_b <= '0'; + next_dummy <= '0'; + + v_stack_idx := stack_idx(i_reg); + + case state is + when fetch => + sync <= '1'; + + if interrupt='1' then + pc_oper <= keep; + next_rwn <= '0'; + next_dout <= reg_pch; + next_state <= push1; + next_amux <= c_amux_stack; + else + next_state <= decode; + next_set_b <= '1'; + end if; + + when decode => + adl_oper <= load_bus; + adh_oper <= clear; + + if is_absolute(i_reg) then + if is_abs_jump(i_reg) then + next_state <= jump; + else + next_state <= absolute; + end if; + elsif is_implied(i_reg) then + pc_oper <= keep; + if is_stack(i_reg) then -- PHP, PLP, PHA, PLA + next_amux <= c_amux_stack; + case v_stack_idx is + when "00" => -- PHP + next_state <= push3; + next_rwn <= '0'; + next_dout <= reg_flags; + + when "10" => -- PHA + next_state <= push3; + next_rwn <= '0'; + next_dout <= reg_accu; + + when others => + next_state <= pull1; + end case; + else + next_state <= fetch; + end if; + elsif is_zeropage(i_reg) then + next_amux <= c_amux_addr; + if is_indirect(i_reg) then + if is_postindexed(i_reg) then + next_state <= zp_indir; + else + next_state <= zp; + next_dummy <= '1'; + end if; + else + next_state <= zp; + if is_store(i_reg) and not is_postindexed(i_reg) then + next_rwn <= '0'; + next_dout <= reg_axy; + end if; + end if; + elsif is_relative(i_reg) then + next_state <= branch; + elsif is_stack(i_reg) then -- non-implied stack operations like BRK, JSR, RTI and RTS + next_amux <= c_amux_stack; + case v_stack_idx is + when c_stack_idx_brk => +-- next_set_b <= '1'; + next_rwn <= '0'; + next_dout <= reg_pch; + next_state <= push1; + when c_stack_idx_jsr => + next_dreg <= '0'; + next_dout <= reg_pch; + next_state <= jump_sub; + when c_stack_idx_rti => + next_state <= pull1; + when c_stack_idx_rts => + next_state <= pull2; + when others => + null; + end case; + elsif is_immediate(i_reg) then + next_state <= fetch; + end if; + + when absolute => + next_state <= abs_hi; + next_amux <= c_amux_addr; + adh_oper <= load_bus; + if is_postindexed(i_reg) then + adl_oper <= add_idx; + elsif not is_zeropage(i_reg) then + if is_store(i_reg) then + next_rwn <='0'; + next_dout <= reg_axy; + end if; + end if; + if is_zeropage(i_reg) then + pc_oper <= keep; + else + pc_oper <= increment; + end if; + + when abs_hi => + pc_oper <= keep; + if is_postindexed(i_reg) then + if is_load(i_reg) and index_carry='0' then + next_amux <= c_amux_pc; + next_state <= fetch; + else + next_amux <= c_amux_addr; + next_state <= abs_fix; + if index_carry='1' then + adh_oper <= increment; + end if; + end if; + if is_store(i_reg) then + next_rwn <= '0'; + next_dout <= reg_axy; + end if; + else -- not post-indexed + if is_jump(i_reg) then + next_amux <= c_amux_addr; + next_state <= jump; + adl_oper <= increment; + elsif is_rmw(i_reg) then + next_rwn <= '0'; + next_dout <= reg_d; + next_dummy <= '1'; + next_state <= rmw1; + next_amux <= c_amux_addr; + else + next_state <= fetch; + next_amux <= c_amux_pc; + end if; + end if; + + when abs_fix => + pc_oper <= keep; + + if is_rmw(i_reg) then + next_state <= rmw1; + next_amux <= c_amux_addr; + next_rwn <= '0'; + next_dout <= reg_d; + next_dummy <= '1'; + else + next_state <= fetch; + next_amux <= c_amux_pc; + end if; + + when branch => + next_amux <= c_amux_pc; + if branch_taken then + pc_oper <= from_alu; -- add offset + next_state <= branch_fix; + else + pc_oper <= increment; + next_state <= decode; + sync <= '1'; + end if; + + when branch_fix => + next_amux <= c_amux_pc; + + if pc_carry='1' then + next_state <= fetch; + pc_oper <= keep; -- this will fix the PCH, since the carry is set + else + sync <= '1'; + next_state <= decode; + pc_oper <= increment; + end if; + + when indir1 => + pc_oper <= keep; + next_state <= indir2; + next_amux <= c_amux_addr; + adl_oper <= copy_dreg; + adh_oper <= load_bus; + + if is_store(i_reg) then + next_rwn <= '0'; + next_dout <= reg_axy; + end if; + + when indir2 => + pc_oper <= keep; + if is_rmw(i_reg) then + next_dummy <= '1'; + next_rwn <= '0'; + next_dout <= reg_d; + next_state <= rmw1; + next_amux <= c_amux_addr; + else + next_state <= fetch; + next_amux <= c_amux_pc; + end if; + + when jump_sub => + next_state <= push1; + pc_oper <= keep; + next_dout <= reg_pch; + next_rwn <= '0'; + next_dreg <= '0'; + next_amux <= c_amux_stack; + + when jump => + pc_oper <= copy; + next_amux <= c_amux_pc; + if is_stack(i_reg) and v_stack_idx=c_stack_idx_rts and vectoring='0' then + next_state <= retrn; + else + next_state <= fetch; + end if; + + when retrn => + pc_oper <= increment; + next_state <= fetch; + + when pull1 => + s_oper <= increment; + next_state <= pull2; + next_amux <= c_amux_stack; + pc_oper <= keep; + + when pull2 => + pc_oper <= keep; + if is_implied(i_reg) then + next_state <= fetch; + next_amux <= c_amux_pc; + next_cp_p <= not v_stack_idx(1); -- only for PLP + else -- it was a stack operation, but not implied (RTS/RTI) + s_oper <= increment; + next_state <= pull3; + next_amux <= c_amux_stack; + next_cp_p <= not v_stack_idx(0); -- only for RTI + end if; + + when pull3 => + pc_oper <= keep; + s_oper <= increment; + next_state <= jump; + next_amux <= c_amux_stack; + + when push1 => + pc_oper <= keep; + s_oper <= decrement; + next_state <= push2; + next_amux <= c_amux_stack; + next_rwn <= '0'; + next_dreg <= '0'; + next_dout <= reg_pcl; + + when push2 => + pc_oper <= keep; + s_oper <= decrement; + if (v_stack_idx=c_stack_idx_jsr) and vectoring='0' then + next_state <= jump; + next_amux <= c_amux_pc; + else + next_state <= push3; + next_rwn <= '0'; + next_dout <= reg_flags; + next_amux <= c_amux_stack; + end if; + + when push3 => + pc_oper <= keep; + s_oper <= decrement; + if is_implied(i_reg) and vectoring='0' then -- PHP, PHA + next_amux <= c_amux_pc; + next_state <= fetch; + else + next_state <= vector; + next_amux <= c_amux_vector; + end if; + + when rmw1 => + pc_oper <= keep; + next_state <= rmw2; + next_amux <= c_amux_addr; + next_rwn <= '0'; + next_dout <= shift_res; + + when rmw2 => + pc_oper <= keep; + next_state <= fetch; + next_amux <= c_amux_pc; + + when vector => + next_state <= jump; + pc_oper <= keep; + next_amux <= c_amux_vector; + + when startup => + next_state <= vector; + pc_oper <= keep; + next_amux <= c_amux_vector; + + when zp => + pc_oper <= keep; + if is_postindexed(i_reg) or is_indirect(i_reg) then + adl_oper <= add_idx; + next_state <= zp_idx; + next_amux <= c_amux_addr; + if is_postindexed(i_reg) and is_store(i_reg) then + next_rwn <= '0'; + next_dout <= reg_axy; + end if; + elsif is_rmw(i_reg) then + next_dummy <= '1'; + next_state <= rmw1; + next_amux <= c_amux_addr; + next_rwn <= '0'; + next_dout <= reg_d; + else + next_state <= fetch; + next_amux <= c_amux_pc; + end if; + + when zp_idx => + pc_oper <= keep; + if is_indirect(i_reg) then + next_state <= indir1; + adl_oper <= increment; + next_amux <= c_amux_addr; + elsif is_rmw(i_reg) then + next_state <= rmw1; + next_amux <= c_amux_addr; + next_rwn <= '0'; + next_dout <= reg_d; + else + next_state <= fetch; + next_amux <= c_amux_pc; + end if; + + when zp_indir => + pc_oper <= keep; + next_state <= absolute; + next_amux <= c_amux_addr; + adl_oper <= increment; + + when others => + null; + end case; + end process; + + reg_update <= '1' when (state = fetch) and vectoring='0' and + not is_stack(i_reg) and not is_relative(i_reg) else '0'; + + vect_bit <= '0' when state = vector else '1'; + + process(clock) + begin + if rising_edge(clock) then + if clock_en='1' then + state <= next_state; + a_mux <= next_amux; + dout_mux <= next_dout; + rwn <= next_rwn; + latch_dreg <= next_dreg and next_rwn; -- disable dreg latch for writes + copy_d2p <= next_cp_p; + set_b <= next_set_b; + dummy_cycle <= next_dummy; + + if next_amux = c_amux_vector or next_amux = c_amux_pc then + a16 <= '1'; + else + a16 <= '0'; + end if; + + if state = fetch then + vectoring <= interrupt; + end if; + end if; + if reset='1' then + a16 <= '1'; + state <= startup; --vector; + a_mux <= c_amux_vector; + rwn <= '1'; + latch_dreg <= '1'; + dout_mux <= reg_d; + copy_d2p <= '0'; + set_b <= '0'; + vectoring <= '0'; + dummy_cycle <= '0'; + end if; + end if; + end process; +end gideon; + diff --git a/cores/c16/1541ultimate2cpu/proc_core.vhd b/cores/c16/1541ultimate2cpu/proc_core.vhd new file mode 100644 index 0000000..8b7c7c2 --- /dev/null +++ b/cores/c16/1541ultimate2cpu/proc_core.vhd @@ -0,0 +1,233 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; +use ieee.std_logic_arith.all; + +library work; +use work.pkg_6502_defs.all; + +entity proc_core is +generic ( + vector_page : std_logic_vector(15 downto 4) := X"FFF"; + support_bcd : boolean := true ); +port( + clock : in std_logic; + clock_en : in std_logic; + reset : in std_logic; + + irq_n : in std_logic := '1'; + nmi_n : in std_logic := '1'; + so_n : in std_logic := '1'; + + sync_out : out std_logic; + pc_out : out std_logic_vector(15 downto 0); + inst_out : out std_logic_vector(7 downto 0); + addr_out : out std_logic_vector(16 downto 0); + data_in : in std_logic_vector(7 downto 0); + data_out : out std_logic_vector(7 downto 0); + read_write_n : out std_logic ); + +end proc_core; + +architecture structural of proc_core is + signal index_carry : std_logic; + signal pc_carry : std_logic; + signal branch_taken : boolean; + signal i_reg : std_logic_vector(7 downto 0); + signal d_reg : std_logic_vector(7 downto 0); + signal a_reg : std_logic_vector(7 downto 0); + signal x_reg : std_logic_vector(7 downto 0); + signal y_reg : std_logic_vector(7 downto 0); + signal s_reg : std_logic_vector(7 downto 0); + signal p_reg : std_logic_vector(7 downto 0); + + signal latch_dreg : std_logic; + signal reg_update : std_logic; + signal copy_d2p : std_logic; + signal sync : std_logic; + signal rwn : std_logic; + signal vect_bit : std_logic; + signal a_mux : t_amux; + signal pc_oper : t_pc_oper; + signal s_oper : t_sp_oper; + signal adl_oper : t_adl_oper; + signal adh_oper : t_adh_oper; + signal dout_mux : t_dout_mux; + + signal alu_out : std_logic_vector(7 downto 0); + signal mem_out : std_logic_vector(7 downto 0); + signal impl_out : std_logic_vector(7 downto 0); + + signal set_a : std_logic; + signal set_x : std_logic; + signal set_y : std_logic; + signal set_s : std_logic; + + signal vect_addr : std_logic_vector(3 downto 0); + signal interrupt : std_logic; + + signal new_flags : std_logic_vector(7 downto 0); + signal n_out : std_logic; + signal v_out : std_logic; + signal c_out : std_logic; + signal z_out : std_logic; + signal d_out : std_logic; + signal i_out : std_logic; + signal set_b : std_logic; + signal clear_b : std_logic; + signal a16 : std_logic; +begin + inst_out <= i_reg; -- for debug only + + new_flags(7) <= n_out; + new_flags(6) <= v_out; + new_flags(5) <= '1'; + new_flags(4) <= p_reg(4); + new_flags(3) <= d_out; + new_flags(2) <= i_out; + new_flags(1) <= z_out; + new_flags(0) <= c_out; + + ctrl: entity work.proc_control + port map ( + clock => clock, + clock_en => clock_en, + reset => reset, + + interrupt => interrupt, + i_reg => i_reg, + index_carry => index_carry, + pc_carry => pc_carry, + branch_taken => branch_taken, + + sync => sync, + latch_dreg => latch_dreg, + reg_update => reg_update, + set_b => set_b, + copy_d2p => copy_d2p, + vect_bit => vect_bit, + a16 => a16, + rwn => rwn, + a_mux => a_mux, + dout_mux => dout_mux, + pc_oper => pc_oper, + s_oper => s_oper, + adl_oper => adl_oper, + adh_oper => adh_oper ); + + oper: entity work.data_oper + generic map ( + support_bcd => support_bcd ) + port map ( + inst => i_reg, + + n_in => p_reg(7), + v_in => p_reg(6), + z_in => p_reg(1), + c_in => p_reg(0), + d_in => p_reg(3), + i_in => p_reg(2), + + data_in => d_reg, + a_reg => a_reg, + x_reg => x_reg, + y_reg => y_reg, + s_reg => s_reg, + + alu_out => alu_out, + mem_out => mem_out, + impl_out => impl_out, + + set_a => set_a, + set_x => set_x, + set_y => set_y, + set_s => set_s, + + n_out => n_out, + v_out => v_out, + z_out => z_out, + c_out => c_out, + d_out => d_out, + i_out => i_out ); + + regs: entity work.proc_registers + generic map ( + vector_page => vector_page ) + port map ( + clock => clock, + clock_en => clock_en, + reset => reset, + + -- package pins + data_in => data_in, + data_out => data_out, + so_n => so_n, + + -- data from "data_oper" + alu_data => alu_out, + mem_data => mem_out, + new_flags => new_flags, + + -- from implied handler + set_a => set_a, + set_x => set_x, + set_y => set_y, + set_s => set_s, + set_data => impl_out, + + -- from interrupt controller + vect_addr => vect_addr, + interrupt => interrupt, + set_b => set_b, + clear_b => clear_b, + + -- from processor state machine and decoder + sync => sync, + latch_dreg => latch_dreg, + vect_bit => vect_bit, + reg_update => reg_update, + copy_d2p => copy_d2p, + a_mux => a_mux, + dout_mux => dout_mux, + pc_oper => pc_oper, + s_oper => s_oper, + adl_oper => adl_oper, + adh_oper => adh_oper, + + -- outputs to processor state machine + i_reg => i_reg, + index_carry => index_carry, + pc_carry => pc_carry, + branch_taken => branch_taken, + + -- register outputs + addr_out => addr_out(15 downto 0), + + d_reg => d_reg, + a_reg => a_reg, + x_reg => x_reg, + y_reg => y_reg, + s_reg => s_reg, + p_reg => p_reg, + pc_out => pc_out ); + + intr: entity work.proc_interrupt + port map ( + clock => clock, + clock_en => clock_en, + reset => reset, + + irq_n => irq_n, + nmi_n => nmi_n, + + i_flag => p_reg(2), + clear_b => clear_b, + + vect_bit => vect_bit, + interrupt => interrupt, + vect_addr => vect_addr ); + + read_write_n <= rwn; + addr_out(16) <= a16; + sync_out <= sync; +end structural; diff --git a/cores/c16/1541ultimate2cpu/proc_interrupt.vhd b/cores/c16/1541ultimate2cpu/proc_interrupt.vhd new file mode 100644 index 0000000..5aa5ffb --- /dev/null +++ b/cores/c16/1541ultimate2cpu/proc_interrupt.vhd @@ -0,0 +1,83 @@ +library ieee; +use ieee.std_logic_1164.all; + +entity proc_interrupt is +port ( + clock : in std_logic; + clock_en : in std_logic; + reset : in std_logic; + + irq_n : in std_logic; + nmi_n : in std_logic; + + i_flag : in std_logic; + clear_b : out std_logic; + + vect_bit : in std_logic; + interrupt : out std_logic; + vect_addr : out std_logic_vector(3 downto 0) ); + +end proc_interrupt; + +architecture gideon of proc_interrupt is + signal irq_c : std_logic := '0'; + signal nmi_c : std_logic := '0'; + signal nmi_d : std_logic := '0'; + signal nmi_act : std_logic := '0'; + signal vect_h : std_logic_vector(1 downto 0) := "00"; + type state_t is (idle, do_irq, do_nmi); + signal state : state_t; +begin + vect_addr <= '1' & vect_h & vect_bit; + interrupt <= irq_c or nmi_act; + + process(clock) + begin + if rising_edge(clock) then + irq_c <= not (irq_n or i_flag); + nmi_c <= not nmi_n; + clear_b <= '0'; + + if clock_en='1' then + nmi_d <= nmi_c; + if nmi_d = '0' and nmi_c = '1' then -- edge + nmi_act <= '1'; + end if; + + case state is + when idle => + vect_h <= "11"; -- FE/FF + if nmi_act = '1' then + vect_h <= "01"; -- FA/FB + state <= do_nmi; + elsif irq_c = '1' then + state <= do_irq; + clear_b <= '1'; + end if; + + when do_irq => + if vect_bit='0' or irq_c='0' then + state <= idle; + end if; + + when do_nmi => + if vect_bit='0' then + nmi_act <= '0'; + state <= idle; + end if; + + when others => + state <= idle; + + end case; + end if; + + if reset='1' then + vect_h <= "10"; -- FC/FD 1100 + state <= do_nmi; + nmi_act <= '0'; + end if; + end if; + end process; + +end gideon; diff --git a/cores/c16/1541ultimate2cpu/proc_registers.vhd b/cores/c16/1541ultimate2cpu/proc_registers.vhd new file mode 100644 index 0000000..ff2cae5 --- /dev/null +++ b/cores/c16/1541ultimate2cpu/proc_registers.vhd @@ -0,0 +1,303 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; +use ieee.std_logic_arith.all; + +library work; +use work.pkg_6502_defs.all; +use work.pkg_6502_decode.all; + +entity proc_registers is +generic ( + vector_page : std_logic_vector(15 downto 4) := X"FFF" ); +port ( + clock : in std_logic; + clock_en : in std_logic; + reset : in std_logic; + + -- package pins + data_in : in std_logic_vector(7 downto 0); + data_out : out std_logic_vector(7 downto 0); + + so_n : in std_logic := '1'; + + -- data from "data_oper" + alu_data : in std_logic_vector(7 downto 0); + mem_data : in std_logic_vector(7 downto 0); + new_flags : in std_logic_vector(7 downto 0); + + -- from implied handler + set_a : in std_logic; + set_x : in std_logic; + set_y : in std_logic; + set_s : in std_logic; + set_data : in std_logic_vector(7 downto 0); + + -- interrupt pins + interrupt : in std_logic; + vect_addr : in std_logic_vector(3 downto 0); + set_b : in std_logic; + clear_b : in std_logic; + + -- from processor state machine and decoder + sync : in std_logic; -- latch ireg + latch_dreg : in std_logic; + vect_bit : in std_logic; + reg_update : in std_logic; + copy_d2p : in std_logic; + a_mux : in t_amux; + dout_mux : in t_dout_mux; + pc_oper : in t_pc_oper; + s_oper : in t_sp_oper; + adl_oper : in t_adl_oper; + adh_oper : in t_adh_oper; + + -- outputs to processor state machine + i_reg : out std_logic_vector(7 downto 0) := X"00"; + index_carry : out std_logic; + pc_carry : out std_logic; + branch_taken : out boolean; + + -- register outputs + addr_out : out std_logic_vector(15 downto 0) := X"FFFF"; + + d_reg : out std_logic_vector(7 downto 0) := X"00"; + a_reg : out std_logic_vector(7 downto 0) := X"00"; + x_reg : out std_logic_vector(7 downto 0) := X"00"; + y_reg : out std_logic_vector(7 downto 0) := X"00"; + s_reg : out std_logic_vector(7 downto 0) := X"00"; + p_reg : out std_logic_vector(7 downto 0) := X"00"; + pc_out : out std_logic_vector(15 downto 0) ); +end proc_registers; + +architecture gideon of proc_registers is +-- signal a_reg : std_logic_vector(7 downto 0); + signal dreg : std_logic_vector(7 downto 0) := X"00"; + signal a_reg_i : std_logic_vector(7 downto 0) := X"00"; + signal x_reg_i : std_logic_vector(7 downto 0) := X"00"; + signal y_reg_i : std_logic_vector(7 downto 0) := X"00"; + signal selected_idx : std_logic_vector(7 downto 0) := X"00"; + signal i_reg_i : std_logic_vector(7 downto 0) := X"00"; + signal s_reg_i : std_logic_vector(7 downto 0) := X"00"; + signal p_reg_i : std_logic_vector(7 downto 0) := X"30"; + signal pcl, pch : std_logic_vector(7 downto 0) := X"FF"; + signal adl, adh : std_logic_vector(7 downto 0) := X"00"; + signal pc_carry_i : std_logic; + signal pc_carry_d : std_logic; + signal branch_flag : std_logic; + signal reg_out : std_logic_vector(7 downto 0); + signal vect : std_logic_vector(3 downto 0) := "1111"; + signal dreg_zero : std_logic; + + alias C_flag : std_logic is p_reg_i(0); + alias Z_flag : std_logic is p_reg_i(1); + alias I_flag : std_logic is p_reg_i(2); + alias D_flag : std_logic is p_reg_i(3); + alias B_flag : std_logic is p_reg_i(4); + alias V_flag : std_logic is p_reg_i(6); + alias N_flag : std_logic is p_reg_i(7); + +begin + dreg_zero <= '1' when dreg=X"00" else '0'; + + process(clock) + variable pcl_t : std_logic_vector(8 downto 0); + variable adl_t : std_logic_vector(8 downto 0); + begin + if rising_edge(clock) then + if clock_en='1' then + -- Data Register + if latch_dreg='1' then + dreg <= data_in; + end if; + + -- Flags Register + if copy_d2p = '1' then + p_reg_i <= dreg; + elsif reg_update='1' then + p_reg_i <= new_flags; + end if; + + if vect_bit='0' then + I_flag <= '1'; + end if; + + if set_b='1' then + B_flag <= '1'; + elsif clear_b='1' then + B_flag <= '0'; + end if; + + if so_n='0' then -- only 1 bit is affected, so no syncronization needed + V_flag <= '1'; + end if; + + -- Instruction Register + if sync='1' then + i_reg_i <= data_in; + + -- Fix for PLA only :( + if load_a(i_reg_i) then + a_reg_i <= dreg; + N_flag <= dreg(7); + Z_flag <= dreg_zero; + end if; + end if; + + -- Logic for the Program Counter + pc_carry_i <= '0'; + case pc_oper is + when increment => + if pcl = X"FF" then + pch <= pch + 1; + end if; + pcl <= pcl + 1; + + when copy => + pcl <= dreg; + pch <= data_in; + + when from_alu => + pcl_t := ('0' & pcl) + (dreg(7) & dreg); -- sign extended 1 bit + pcl <= pcl_t(7 downto 0); + pc_carry_i <= pcl_t(8); + pc_carry_d <= dreg(7); + + when others => -- keep (and fix) + if pc_carry_i='1' then + if pc_carry_d='1' then + pch <= pch - 1; + else + pch <= pch + 1; + end if; + end if; + end case; + + -- Logic for the Address register + case adl_oper is + when increment => + adl <= adl + 1; + + when add_idx => + adl_t := ('0' & dreg) + ('0' & selected_idx); + adl <= adl_t(7 downto 0); + index_carry <= adl_t(8); + + when load_bus => + adl <= data_in; + + when copy_dreg => + adl <= dreg; + + when others => + null; + + end case; + + case adh_oper is + when increment => + adh <= adh + 1; + + when clear => + adh <= (others => '0'); + + when load_bus => + adh <= data_in; + + when others => + null; + end case; + + -- Logic for ALU register + if reg_update='1' then + if set_a='1' then + a_reg_i <= set_data; + elsif store_a_from_alu(i_reg_i) then + a_reg_i <= alu_data; + end if; + end if; + + -- Logic for Index registers + if reg_update='1' then + if set_x='1' then + x_reg_i <= set_data; + elsif load_x(i_reg_i) then + x_reg_i <= alu_data; --dreg; -- alu is okay, too (they should be the same) + end if; + end if; + + if reg_update='1' then + if set_y='1' then + y_reg_i <= set_data; + elsif load_y(i_reg_i) then + y_reg_i <= dreg; + end if; + end if; + + -- Logic for the Stack Pointer + if set_s='1' then + s_reg_i <= set_data; + else + case s_oper is + when increment => + s_reg_i <= s_reg_i + 1; + + when decrement => + s_reg_i <= s_reg_i - 1; + + when others => + null; + end case; + end if; + end if; + -- Reset + if reset='1' then + p_reg_i <= X"34"; -- I=1 + index_carry <= '0'; + end if; + end if; + end process; + + with i_reg_i(7 downto 6) select branch_flag <= + N_flag when "00", + V_flag when "01", + C_flag when "10", + Z_flag when "11", + '0' when others; + + branch_taken <= (branch_flag xor not i_reg_i(5))='1'; + + with a_mux select addr_out <= + vector_page & vect_addr when 0, + adh & adl when 1, + X"01" & s_reg_i when 2, + pch & pcl when 3; + + with i_reg_i(1 downto 0) select reg_out <= + y_reg_i when "00", + a_reg_i when "01", + x_reg_i when "10", + a_reg_i and x_reg_i when others; + + with dout_mux select data_out <= + dreg when reg_d, + a_reg_i when reg_accu, + reg_out when reg_axy, + p_reg_i or X"20" when reg_flags, + pcl when reg_pcl, + pch when reg_pch, + mem_data when shift_res, + X"FF" when others; + + selected_idx <= y_reg_i when select_index_y(i_reg_i) else x_reg_i; + + pc_carry <= pc_carry_i; + s_reg <= s_reg_i; + p_reg <= p_reg_i; + i_reg <= i_reg_i; + a_reg <= a_reg_i; + x_reg <= x_reg_i; + y_reg <= y_reg_i; + d_reg <= dreg; + pc_out <= pch & pcl; +end gideon; diff --git a/cores/c16/1541ultimate2cpu/shifter.vhd b/cores/c16/1541ultimate2cpu/shifter.vhd new file mode 100644 index 0000000..56bce45 --- /dev/null +++ b/cores/c16/1541ultimate2cpu/shifter.vhd @@ -0,0 +1,60 @@ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; + +entity shifter is +port ( + operation : in std_logic_vector(2 downto 0); + enable : in std_logic := '1'; -- instruction(1) + + c_in : in std_logic; + n_in : in std_logic; + z_in : in std_logic; + + data_in : in std_logic_vector(7 downto 0); + + c_out : out std_logic; + n_out : out std_logic; + z_out : out std_logic; + + data_out : out std_logic_vector(7 downto 0) := X"00"); + +end shifter; + +architecture gideon of shifter is + signal data_out_i : std_logic_vector(7 downto 0) := X"00"; + signal zero : std_logic := '0'; + signal oper4 : std_logic_vector(3 downto 0) := X"0"; +begin +-- ASL $nn ROL $nn LSR $nn ROR $nn STX $nn LDX $nn DEC $nn INC $nn + + with operation select data_out_i <= + data_in(6 downto 0) & '0' when "000", + data_in(6 downto 0) & c_in when "001", + '0' & data_in(7 downto 1) when "010", + c_in & data_in(7 downto 1) when "011", + data_in - 1 when "110", + data_in + 1 when "111", + data_in when others; + + zero <= '1' when data_out_i = X"00" else '0'; + + oper4 <= enable & operation; + + with oper4 select c_out <= + data_in(7) when "1000" | "1001", + data_in(0) when "1010" | "1011", + c_in when others; + + with oper4 select z_out <= + zero when "1000" | "1001" | "1010" | "1011" | "1101" | "1110" | "1111", + z_in when others; + + with oper4 select n_out <= + data_out_i(7) when "1000" | "1001" | "1010" | "1011" | "1101" | "1110" | "1111", + n_in when others; + + data_out <= data_out_i when enable='1' else data_in; + +end gideon; \ No newline at end of file diff --git a/cores/c16/c1541/c1541_logic.vhd b/cores/c16/c1541/c1541_logic.vhd index 87e022e..3b52e50 100644 --- a/cores/c16/c1541/c1541_logic.vhd +++ b/cores/c16/c1541/c1541_logic.vhd @@ -112,8 +112,7 @@ begin reset_n <= not reset; process (clk_32M, reset) - variable count : std_logic_vector(8 downto 0) := (others => '0'); - alias hcnt : std_logic_vector(1 downto 0) is count(4 downto 3); + variable count : std_logic_vector(4 downto 0) := (others => '0'); begin if rising_edge(clk_32M) then -- generate 1MHz pulse @@ -122,17 +121,12 @@ begin if count(4 downto 0) = "01000" then clk_1M_pulse <= '1'; end if; - -- if count = "000100000" then -- DAR divide by 33 (otherwise real c64 miss EOI acknowledge) - if count = "000011111" then -- TH - C16 MiST: zero after 31, restart from 1 - count := (0 => '1', others => '0'); - else -- DAR - count := std_logic_vector(unsigned(count) + 1); - end if; -- DAR + count := std_logic_vector(unsigned(count) + 1); end if; - p2_h <= not hcnt(1); + p2_h <= not count(4); -- for original m6522 design that requires a real clock --- clk_4M_en <= not count(2); + -- clk_4M_en <= not count(2); -- for version 002 with clock enable if count(2 downto 0) = "111" then @@ -159,10 +153,10 @@ begin -- hook up UC1 ports -- - uc1_cs1 <= cpu_a(11); + uc1_cs1 <= '1'; --uc1_cs2_n: see decode logic above -- CA1 - --uc1_ca1_i <= not sb_atn_in; -- DAR comment : synched with clk_4M_en see below + uc1_ca1_i <= not sb_atn_in; -- PA uc1_pa_i(0) <= tr00_sense_n; uc1_pa_i(7 downto 1) <= (others => '0'); -- NC @@ -187,7 +181,7 @@ begin -- hook up UC3 ports -- - uc3_cs1 <= cpu_a(11); + uc3_cs1 <= '1'; --uc3_cs2_n: see decode logic above -- CA1 uc3_ca1_i <= cpu_so_n; -- byte ready gated with soe @@ -223,54 +217,19 @@ begin -- external connections -- ATN never driven by the 1541 sb_atn_oe <= '0'; - - - -- DAR - process (clk_32M) - begin - if rising_edge(clk_32M) then - if clk_4M_en = '1' then - uc1_ca1_i <= not sb_atn_in; -- DAR sample external atn to ensure not missing edge within VIA - end if; - end if; - end process; - process (clk_32M, cpu_sync) - begin - if rising_edge(clk_32M) then - if cpu_sync = '1' then - dbg_adr_fetch <= cpu_a(15 downto 0); - end if; - end if; - end process; - dbg_cpu_irq <= cpu_irq_n; - -- DAR - - cpu_inst : entity work.T65 - port map - ( - Mode => "00", -- 6502 - Res_n => reset_n, - Enable => clk_1M_pulse, - Clk => clk_32M, - Rdy => '1', - Abort_n => '1', - IRQ_n => cpu_irq_n, - NMI_n => '1', - SO_n => cpu_so_n, - R_W_n => cpu_rw_n, - Sync => cpu_sync, -- open -- DAR - EF => open, - MF => open, - XF => open, - ML_n => open, - VP_n => open, - VDA => open, - VPA => open, - A => cpu_a, - DI => cpu_di, - DO => cpu_do - ); + cpu: work.proc_core + port map( + reset => reset, + clock_en => clk_1M_pulse, + clock => clk_32M, + so_n => cpu_so_n, + irq_n => cpu_irq_n, + read_write_n => cpu_rw_n, + addr_out => cpu_a(16 downto 0), + data_in => cpu_di, + data_out => cpu_do + ); rom_inst : entity work.sprom generic map diff --git a/cores/c16/c16_mist.qsf b/cores/c16/c16_mist.qsf index ae321c1..2c29a9e 100644 --- a/cores/c16/c16_mist.qsf +++ b/cores/c16/c16_mist.qsf @@ -167,7 +167,7 @@ set_global_assignment -name USE_CONFIGURATION_DEVICE OFF # SignalTap II Assignments # ======================== set_global_assignment -name ENABLE_SIGNALTAP OFF -set_global_assignment -name USE_SIGNALTAP_FILE output_files/stp1.stp +set_global_assignment -name USE_SIGNALTAP_FILE output_files/stp2.stp # Power Estimation Assignments # ============================ @@ -350,7 +350,21 @@ set_global_assignment -name VHDL_FILE c1541/sprom.vhd set_global_assignment -name VHDL_FILE c1541/c1541_sd.vhd set_global_assignment -name VHDL_FILE c1541/c1541_logic.vhd set_global_assignment -name SYSTEMVERILOG_FILE c1541/mist_sd_card.sv +set_global_assignment -name VHDL_FILE 1541ultimate2cpu/shifter.vhd +set_global_assignment -name VHDL_FILE 1541ultimate2cpu/proc_registers.vhd +set_global_assignment -name VHDL_FILE 1541ultimate2cpu/proc_interrupt.vhd +set_global_assignment -name VHDL_FILE 1541ultimate2cpu/proc_core.vhd +set_global_assignment -name VHDL_FILE 1541ultimate2cpu/proc_control.vhd +set_global_assignment -name VHDL_FILE 1541ultimate2cpu/pkg_6502_opcodes.vhd +set_global_assignment -name VHDL_FILE 1541ultimate2cpu/pkg_6502_defs.vhd +set_global_assignment -name VHDL_FILE 1541ultimate2cpu/pkg_6502_decode.vhd +set_global_assignment -name VHDL_FILE 1541ultimate2cpu/implied.vhd +set_global_assignment -name VHDL_FILE 1541ultimate2cpu/data_oper.vhd +set_global_assignment -name VHDL_FILE 1541ultimate2cpu/cpu6502.vhd +set_global_assignment -name VHDL_FILE 1541ultimate2cpu/bit_cpx_cpy.vhd +set_global_assignment -name VHDL_FILE 1541ultimate2cpu/alu.vhd set_global_assignment -name VHDL_FILE t65/T65_Pack.vhd set_global_assignment -name VHDL_FILE t65/T65_MCode.vhd set_global_assignment -name VHDL_FILE t65/T65_ALU.vhd -set_global_assignment -name VHDL_FILE t65/T65.vhd \ No newline at end of file +set_global_assignment -name VHDL_FILE t65/T65.vhd +set_global_assignment -name SIGNALTAP_FILE output_files/stp2.stp \ No newline at end of file