diff --git a/firmware/AtomBusMon.c b/firmware/AtomBusMon.c index 69000b5..cdf2980 100644 --- a/firmware/AtomBusMon.c +++ b/firmware/AtomBusMon.c @@ -1,5 +1,6 @@ #include #include +#include #include #include "hd44780.h" @@ -73,7 +74,7 @@ char *modeStrings[7] = { #define VERSION "0.11" #define NUMCMDS 20 -#define MAXBKPTS 4 +#define MAXBKPTS 8 int numbkpts = 0; @@ -236,11 +237,12 @@ void logMode(unsigned int mode) { int first = 1; for (i = 0; i < UNDEFINED; i++) { if (mode & 1) { - if (!first) { - log0(","); - first = 0; + if (first) { + log0("%s", modeStrings[i]); + } else { + log0(", %c%s", tolower(*modeStrings[i]), modeStrings[i] + 1); } - log0("%s", modeStrings[i]); + first = 0; } mode >>= 1; } @@ -368,20 +370,17 @@ void doCmdBreak(char *params, unsigned int mode) { } else { setBreakpoint(i, addr, modes[i] | mode); } - doCmdBList(NULL); return; } } if (numbkpts == MAXBKPTS) { - log0("All breakpoints are already set\n"); - doCmdBList(NULL); + log0("All %d breakpoints are already set\n", numbkpts); return; } numbkpts++; for (i = numbkpts - 2; i >= -1; i--) { if (i == -1 || breakpoints[i] < addr) { setBreakpoint(i + 1, addr, mode); - doCmdBList(NULL); return; } else { breakpoints[i + 1] = breakpoints[i]; @@ -446,7 +445,6 @@ void doCmdBClear(char *params, unsigned int mode) { logMode(mode); log0(" not set at %04X\n", n); } - doCmdBList(NULL); } void doCmdBClearI(char *params) { @@ -487,7 +485,9 @@ void shiftBreakpointRegister(unsigned int addr, unsigned int mode) { void doCmdContinue(char *params) { int i; int status; - doCmdBList(NULL); + + // Step the 6502, otherwise the breakpoint happends again immediately + hwCmd(CMD_STEP, 0); // Disable breakpoints to allow loading hwCmd(CMD_BRKPT_ENABLE, 0); @@ -520,6 +520,7 @@ void doCmdContinue(char *params) { doCmdAddr(); cont = 0; } + Delay_us(10); } while (cont); // Enable single stepping @@ -542,8 +543,6 @@ void initialize() { hwCmd(CMD_RESET, 0); setSingle(1); setTrace(1); - log0("6502 paused...\n"); - doCmdAddr(); } void (*cmdFuncs[NUMCMDS])(char *params) = { @@ -597,6 +596,7 @@ void dispatchCmd(char *cmd) { int main(void) { initialize(); + doCmdContinue(NULL); while (1) { readCmd(command); dispatchCmd(command); diff --git a/ipcore_dir/WatchEvents.xise b/ipcore_dir/WatchEvents.xise index 9f725ac..dc7472b 100644 --- a/ipcore_dir/WatchEvents.xise +++ b/ipcore_dir/WatchEvents.xise @@ -17,11 +17,11 @@ - + - + @@ -29,341 +29,29 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - diff --git a/src/AtomBusMon.vhd b/src/AtomBusMon.vhd index 730ff6e..3a23a90 100644 --- a/src/AtomBusMon.vhd +++ b/src/AtomBusMon.vhd @@ -23,79 +23,86 @@ use work.OhoPack.all ; entity AtomBusMon is - port (clock49 : in std_logic; + generic ( + num_comparators : integer := 8; + reg_width : integer := 22; + fifo_width : integer := 36 + ); + port ( + clock49 : in std_logic; - -- 6502 Signals - Addr : in std_logic_vector(15 downto 0); - Phi2 : in std_logic; - RNW : in std_logic; - Sync : in std_logic; - Rdy : out std_logic; - nRST : inout std_logic; + -- 6502 Signals + Addr : in std_logic_vector(15 downto 0); + Phi2 : in std_logic; + RNW : in std_logic; + Sync : in std_logic; + Rdy : out std_logic; + nRST : inout std_logic; - -- HD44780 LCD - lcd_rs : out std_logic; - lcd_rw : out std_logic; - lcd_e : out std_logic; - lcd_db : inout std_logic_vector(7 downto 4); + -- HD44780 LCD + lcd_rs : out std_logic; + lcd_rw : out std_logic; + lcd_e : out std_logic; + lcd_db : inout std_logic_vector(7 downto 4); - -- AVR Serial Port - avr_RxD : in std_logic; - avr_TxD : out std_logic; + -- AVR Serial Port + avr_RxD : in std_logic; + avr_TxD : out std_logic; - -- GODIL Switches - sw1 : in std_logic; - nsw2 : in std_logic; + -- GODIL Switches + sw1 : in std_logic; + nsw2 : in std_logic; - -- GODIL LEDs - led3 : out std_logic; - led6 : out std_logic; - led8 : out std_logic; + -- GODIL LEDs + led3 : out std_logic; + led6 : out std_logic; + led8 : out std_logic; - -- OHO_DY1 connected to test connector - tmosi : out std_logic; - tdin : out std_logic; - tcclk : out std_logic + -- OHO_DY1 connected to test connector + tmosi : out std_logic; + tdin : out std_logic; + tcclk : out std_logic ); end AtomBusMon; architecture behavioral of AtomBusMon is - signal clock_avr : std_logic; - signal nrst_avr : std_logic; - signal lcd_rw_int : std_logic; - signal lcd_db_in : std_logic_vector(7 downto 4); - signal lcd_db_out : std_logic_vector(7 downto 4); - signal dy_counter : std_logic_vector(31 downto 0); - signal dy_data : y2d_type ; + signal clock_avr : std_logic; + signal nrst_avr : std_logic; + signal lcd_rw_int : std_logic; + signal lcd_db_in : std_logic_vector(7 downto 4); + signal lcd_db_out : std_logic_vector(7 downto 4); + signal dy_counter : std_logic_vector(31 downto 0); + signal dy_data : y2d_type ; - signal mux : std_logic_vector(7 downto 0); - signal muxsel : std_logic_vector(2 downto 0); - signal cmd_edge : std_logic; - signal cmd_edge1 : std_logic; - signal cmd_edge2 : std_logic; - signal cmd : std_logic_vector(3 downto 0); + signal mux : std_logic_vector(7 downto 0); + signal muxsel : std_logic_vector(2 downto 0); + signal cmd_edge : std_logic; + signal cmd_edge1 : std_logic; + signal cmd_edge2 : std_logic; + signal cmd : std_logic_vector(3 downto 0); - signal addr_sync : std_logic_vector(15 downto 0); - signal addr_inst : std_logic_vector(15 downto 0); + signal addr_sync : std_logic_vector(15 downto 0); + signal addr_inst : std_logic_vector(15 downto 0); - signal single : std_logic; - signal reset : std_logic; - signal step : std_logic; + signal single : std_logic; + signal reset : std_logic; + signal step : std_logic; - signal bw_status : std_logic_vector(19 downto 0); + signal bw_status : std_logic_vector(fifo_width - 16 - 1 downto 0); + signal bw_status1 : std_logic_vector(fifo_width - 16 - 1 downto 0); - signal brkpt_reg : std_logic_vector(87 downto 0); + signal brkpt_reg : std_logic_vector(num_comparators * reg_width - 1 downto 0); signal brkpt_enable : std_logic; signal brkpt_active : std_logic; - signal brkpt_active1 : std_logic; - - signal watch_active : std_logic; - signal watch_din : std_logic_vector(35 downto 0); - signal watch_dout : std_logic_vector(35 downto 0); - signal watch_empty : std_logic; - signal watch_rd : std_logic; - signal watch_wr : std_logic; + signal brkpt_active1 : std_logic; + signal watch_active : std_logic; + + signal fifo_din : std_logic_vector(fifo_width - 1 downto 0); + signal fifo_dout : std_logic_vector(fifo_width - 1 downto 0); + signal fifo_empty : std_logic; + signal fifo_rd : std_logic; + signal fifo_wr : std_logic; begin @@ -170,7 +177,7 @@ begin portdin(4) => '0', portdin(5) => '0', portdin(6) => sw1, - portdin(7) => not watch_empty, + portdin(7) => not fifo_empty, portdout => open, -- Mux Port @@ -187,17 +194,17 @@ begin WatchEvents_inst : entity work.WatchEvents port map( clk => Phi2, - din => watch_din, - wr_en => watch_wr, - rd_en => watch_rd, - dout => watch_dout, + din => fifo_din, + wr_en => fifo_wr, + rd_en => fifo_rd, + dout => fifo_dout, full => open, - empty => watch_empty + empty => fifo_empty ); - watch_din <= bw_status & Addr when Sync = '1' else - bw_status & addr_inst; - + + fifo_din <= bw_status1 & addr_inst; + lcd_rw <= lcd_rw_int; lcd_db <= lcd_db_out when lcd_rw_int = '0' else (others => 'Z'); lcd_db_in <= lcd_db; @@ -213,68 +220,69 @@ begin dy_data(1) <= hex & "0000" & Addr(7 downto 4); dy_data(2) <= hex & "0000" & "00" & (not nsw2) & sw1; - mux <= addr_inst(7 downto 0) when muxsel = 0 else - addr_inst(15 downto 8) when muxsel = 1 else - watch_dout(7 downto 0) when muxsel = 2 else - watch_dout(15 downto 8) when muxsel = 3 else - watch_dout(23 downto 16) when muxsel = 4 else - watch_dout(31 downto 24) when muxsel = 5 else - "0000" & watch_dout(35 downto 32) when muxsel = 6 else + mux <= addr_inst(7 downto 0) when muxsel = 0 else + addr_inst(15 downto 8) when muxsel = 1 else + fifo_dout(7 downto 0) when muxsel = 2 else + fifo_dout(15 downto 8) when muxsel = 3 else + fifo_dout(23 downto 16) when muxsel = 4 else + fifo_dout(31 downto 24) when muxsel = 5 else + "0000" & fifo_dout(35 downto 32) when muxsel = 6 else "10101010"; - + + -- Combinatorial set of comparators to decode breakpoint/watch addresses brkpt_active_process: process (brkpt_reg, brkpt_enable, Addr, Sync) - variable bactive : std_logic; - variable wactive : std_logic; - variable status : std_logic_vector(19 downto 0); - variable i : integer; - variable reg_addr : std_logic_vector(15 downto 0); - variable reg_mode_bi : std_logic; + variable i : integer; + variable reg_addr : std_logic_vector(15 downto 0); + variable reg_mode_bi : std_logic; variable reg_mode_bar : std_logic; variable reg_mode_baw : std_logic; - variable reg_mode_wi : std_logic; + variable reg_mode_wi : std_logic; variable reg_mode_war : std_logic; variable reg_mode_waw : std_logic; + variable bactive : std_logic; + variable wactive : std_logic; + variable status : std_logic_vector(19 downto 0); begin bactive := '0'; wactive := '0'; - status := "00001010101010101010"; + status := "00001010101010101010"; if (brkpt_enable = '1') then - for i in 0 to 3 loop - reg_addr := brkpt_reg(i * 22 + 15 downto i * 22); - reg_mode_bi := brkpt_reg(i * 22 + 16); - reg_mode_bar := brkpt_reg(i * 22 + 17); - reg_mode_baw := brkpt_reg(i * 22 + 18); - reg_mode_wi := brkpt_reg(i * 22 + 19); - reg_mode_war := brkpt_reg(i * 22 + 20); - reg_mode_waw := brkpt_reg(i * 22 + 21); + for i in 0 to num_comparators - 1 loop + reg_addr := brkpt_reg(i * reg_width + 15 downto i * reg_width); + reg_mode_bi := brkpt_reg(i * reg_width + 16); + reg_mode_bar := brkpt_reg(i * reg_width + 17); + reg_mode_baw := brkpt_reg(i * reg_width + 18); + reg_mode_wi := brkpt_reg(i * reg_width + 19); + reg_mode_war := brkpt_reg(i * reg_width + 20); + reg_mode_waw := brkpt_reg(i * reg_width + 21); if (Addr = reg_addr) then if (Sync = '1') then if (reg_mode_bi = '1') then bactive := '1'; - status := "0001" & reg_addr; + status := "0001" & reg_addr; end if; if (reg_mode_wi = '1') then wactive := '1'; - status := "1001" & reg_addr; + status := "1001" & reg_addr; end if; else if (RNW = '1') then if (reg_mode_bar = '1') then bactive := '1'; - status := "0010" & reg_addr; + status := "0010" & reg_addr; end if; if (reg_mode_war = '1') then wactive := '1'; - status := "1010" & reg_addr; + status := "1010" & reg_addr; end if; else if (reg_mode_baw = '1') then bactive := '1'; - status := "0100" & reg_addr; + status := "0100" & reg_addr; end if; if (reg_mode_waw = '1') then wactive := '1'; - status := "1100" & reg_addr; + status := "1100" & reg_addr; end if; end if; end if; @@ -283,27 +291,26 @@ begin end if; watch_active <= wactive; brkpt_active <= bactive; - bw_status <= status; + bw_status <= status; end process; - watch_wr <= '1' when watch_active = '1' or (brkpt_active = '1' and brkpt_active1 = '0') else '0'; - - -- 6502 Control + -- 6502 Control Commands + -- 000x Enable/Disable single strpping + -- 001x Enable/Disable breakpoints / watches + -- 010x Load register + -- 011x Reset + -- 1000 Single Step + -- 1001 Watch Read syncProcess: process (Phi2) begin if rising_edge(Phi2) then + -- Command processing cmd_edge1 <= cmd_edge; cmd_edge2 <= cmd_edge1; - watch_rd <= '0'; + fifo_rd <= '0'; + fifo_wr <= '0'; if (cmd_edge2 = '0' and cmd_edge1 = '1') then - -- 000x Enable/Disable single strpping - -- 001x Enable/Disable breakpoints / watches - -- 010x Load register - -- 011x Reset - -- 1000 Single Step - -- 1001 Watch Read - if (cmd(3 downto 1) = "000") then single <= cmd(0); end if; @@ -321,32 +328,34 @@ begin end if; if (cmd(3 downto 0) = "1001") then - watch_rd <= '1'; - end if; - + fifo_rd <= '1'; + end if; end if; + -- Single Stepping + if ((single = '0') or (cmd_edge2 = '0' and cmd_edge1 = '1' and cmd = "1000")) then + Rdy <= (not brkpt_active); + else + Rdy <= (not Sync); + end if; + + -- 6502 Reset needs to be open collector if (reset = '1') then nRST <= '0'; else nRST <= 'Z'; end if; - -- Address monitoring - addr_sync <= Addr; + -- Latch instruction address for the whole cycle if (Sync = '1') then addr_inst <= Addr; end if; -- Breakpoints and Watches written to the FIFO brkpt_active1 <= brkpt_active; - - - -- Single Stepping - if ((single = '0') or (cmd_edge2 = '0' and cmd_edge1 = '1' and cmd = "1000")) then - Rdy <= (not brkpt_active); - else - Rdy <= (not Sync); + bw_status1 <= bw_status; + if watch_active = '1' or (brkpt_active = '1' and brkpt_active1 = '0') then + fifo_wr <= '1'; end if; end if; end process;