Added breakpoint functionality

Change-Id: I82b1162249a1bfed2d340361b205340dfbb70d86
This commit is contained in:
David Banks
2015-06-07 17:58:14 +01:00
parent 30d42b8bd0
commit 10afdff12c
3 changed files with 166 additions and 53 deletions

View File

@@ -7,10 +7,20 @@
#define CTRL_PORT PORTB #define CTRL_PORT PORTB
#define CTRL_DDR DDRB #define CTRL_DDR DDRB
#define CTRL_DIN PINB
// Outputs
#define STEP_MASK 0x01 #define STEP_MASK 0x01
#define SINGLE_MASK 0x02 #define SINGLE_MASK 0x02
#define RESET_MASK 0x04 #define RESET_MASK 0x04
#define CTRL_MASK (SINGLE_MASK | STEP_MASK | RESET_MASK) #define BRKPT_ENABLE_MASK 0x08
#define BRKPT_CLOCK_MASK 0x10
#define BRKPT_DATA_MASK 0x20
// Inputs
#define BRKPT_INTERRUPTED_MASK 0x40
#define BRKPT_ACTIVE_MASK 0x80
#define CTRL_MASK (SINGLE_MASK | STEP_MASK | RESET_MASK | BRKPT_ENABLE_MASK | BRKPT_CLOCK_MASK | BRKPT_DATA_MASK)
#define AL_PORT PORTD #define AL_PORT PORTD
#define AL_DIN PIND #define AL_DIN PIND
@@ -22,7 +32,7 @@
#define AH_MASK 0x00 #define AH_MASK 0x00
#define AH_DDR DDRE #define AH_DDR DDRE
#define VERSION "0.10" #define VERSION "0.11"
#define NUMCMDS 10 #define NUMCMDS 10
#define MAXBKPTS 4 #define MAXBKPTS 4
@@ -43,14 +53,14 @@ unsigned int breakpoints[MAXBKPTS] = {
char *cmdStrings[NUMCMDS] = { char *cmdStrings[NUMCMDS] = {
"help", "help",
"reset", "reset",
"break", "interrupt",
"continue",
"address", "address",
"step", "step",
"trace", "trace",
"blist", "blist",
"bset", "break",
"bclear" "bclear",
"continue",
}; };
#define Delay_us(__us) \ #define Delay_us(__us) \
@@ -105,34 +115,33 @@ void setSingle(int i) {
single = i; single = i;
if (single) { if (single) {
CTRL_PORT |= SINGLE_MASK; CTRL_PORT |= SINGLE_MASK;
log0("Single stepping enabled\n");
} else { } else {
CTRL_PORT &= ~SINGLE_MASK; CTRL_PORT &= ~SINGLE_MASK;
log0("Single stepping disabled\n");
} }
Delay_us(10);
} }
void setTrace(long i) { void setTrace(long i) {
trace = i; trace = i;
if (trace) { if (trace) {
log0("Tracing every %ld instructions\n", trace); log0("Tracing every %ld instructions while single stepping\n", trace);
} else { } else {
log0("Tracing disabled\n"); log0("Tracing disabled\n");
} }
} }
void version() {
log0("Atom Bus Monitor version %s\n", VERSION);
log0("Compiled at %s on %s\n",__TIME__,__DATE__);
}
/******************************************* /*******************************************
* Commands * Commands
*******************************************/ *******************************************/
void notImplemented() {
log0("Not implemented\n");
}
void doCmdHelp(char *params) { void doCmdHelp(char *params) {
int i; int i;
log0("Atom Bus Monitor version %s\n", VERSION); version();
log0("Commands:\n"); log0("Commands:\n");
for (i = 0; i < NUMCMDS; i++) { for (i = 0; i < NUMCMDS; i++) {
log0(" %s\n", cmdStrings[i]); log0(" %s\n", cmdStrings[i]);
@@ -168,10 +177,11 @@ void doCmdStep(char *params) {
for (i = 1; i <= instructions; i++) { for (i = 1; i <= instructions; i++) {
// Step the 6502 // Step the 6502
CTRL_PORT &= ~STEP_MASK; CTRL_PORT &= ~STEP_MASK;
Delay_us(1); Delay_us(2);
CTRL_PORT |= STEP_MASK; CTRL_PORT |= STEP_MASK;
Delay_us(1); Delay_us(2);
if (i == instructions || (trace && (--j == 0))) { if (i == instructions || (trace && (--j == 0))) {
Delay_us(10);
doCmdAddr(); doCmdAddr();
j = trace; j = trace;
} }
@@ -185,15 +195,11 @@ void doCmdReset(char *params) {
CTRL_PORT &= ~RESET_MASK; CTRL_PORT &= ~RESET_MASK;
} }
void doCmdBreak(char *params) { void doCmdInterrupt(char *params) {
setSingle(true); setSingle(1);
doCmdAddr(); doCmdAddr();
} }
void doCmdContinue(char *params) {
setSingle(false);
}
void doCmdTrace(char *params) { void doCmdTrace(char *params) {
long i; long i;
@@ -212,7 +218,7 @@ void doCmdBList(char *params) {
} }
} }
void doCmdBSet(char *params) { void doCmdBreak(char *params) {
int i; int i;
unsigned int addr; unsigned int addr;
sscanf(params, "%x", &addr); sscanf(params, "%x", &addr);
@@ -221,6 +227,14 @@ void doCmdBSet(char *params) {
doCmdBList(NULL); doCmdBList(NULL);
return; return;
} }
for (i = 0; i < numbkpts; i++) {
if (breakpoints[i] == addr) {
log0("Breakpoint already set at %04X\n", addr);
doCmdBList(NULL);
return;
}
}
numbkpts++; numbkpts++;
for (i = numbkpts - 2; i >= -1; i--) { for (i = numbkpts - 2; i >= -1; i--) {
if (i == -1 || breakpoints[i] < addr) { if (i == -1 || breakpoints[i] < addr) {
@@ -228,10 +242,6 @@ void doCmdBSet(char *params) {
breakpoints[i + 1] = addr; breakpoints[i + 1] = addr;
doCmdBList(NULL); doCmdBList(NULL);
return; return;
} else if (breakpoints[i] == addr) {
log0("Breakpoint already set at %04X\n", addr);
doCmdBList(NULL);
return;
} else { } else {
breakpoints[i + 1] = breakpoints[i]; breakpoints[i + 1] = breakpoints[i];
} }
@@ -240,7 +250,7 @@ void doCmdBSet(char *params) {
void doCmdBClear(char *params) { void doCmdBClear(char *params) {
int i; int i;
int n; int n = 0;
sscanf(params, "%d", &n); sscanf(params, "%d", &n);
if (n >= numbkpts) { if (n >= numbkpts) {
log0("Breakpoint %d not set\n", n); log0("Breakpoint %d not set\n", n);
@@ -254,30 +264,89 @@ void doCmdBClear(char *params) {
doCmdBList(NULL); doCmdBList(NULL);
} }
void shiftBreakpointRegister(unsigned int addr) {
int i;
for (i = 0; i < 16; i++) {
CTRL_PORT &= ~BRKPT_CLOCK_MASK;
if (addr & 1) {
CTRL_PORT |= BRKPT_DATA_MASK;
} else {
CTRL_PORT &= ~BRKPT_DATA_MASK;
}
Delay_us(10);
CTRL_PORT |= BRKPT_CLOCK_MASK;
Delay_us(10);
addr >>= 1;
}
}
void doCmdContinue(char *params) {
int i;
int status;
doCmdBList(NULL);
// Disable breakpoints to allow loading
CTRL_PORT &= ~BRKPT_ENABLE_MASK;
// Load breakpoints into comparators
for (i = 0; i < MAXBKPTS; i++) {
shiftBreakpointRegister(i < numbkpts ? breakpoints[i] : 0);
}
// Enable breakpoints
CTRL_PORT |= BRKPT_ENABLE_MASK;
// Disable single stepping
setSingle(0);
// Wait for breakpoint to become active
log0("6502 free running...\n");
do {
status = CTRL_DIN;
} while (!(status & BRKPT_ACTIVE_MASK) && !(status && BRKPT_INTERRUPTED_MASK));
// Output cause
if (status & BRKPT_ACTIVE_MASK) {
log0("Breakpoint hit at ");
} else {
log0("Interrupted at ");
}
doCmdAddr();
// Enable single stepping
setSingle(1);
// Disable breakpoints
CTRL_PORT &= ~BRKPT_ENABLE_MASK;
}
void initialize() { void initialize() {
CTRL_DDR = CTRL_MASK; CTRL_DDR = CTRL_MASK;
AL_DDR = AL_MASK; AL_DDR = AL_MASK;
AH_DDR = AH_MASK; AH_DDR = AH_MASK;
CTRL_PORT &= ~STEP_MASK; CTRL_PORT &= 0;
Serial_Init(57600,57600); Serial_Init(57600,57600);
lcd_init(); lcd_init();
lcd_puts("Addr: xxxx"); lcd_puts("Addr: xxxx");
log0("Atom Bus Monitor\n"); version();
setSingle(false); setSingle(1);
setTrace(0); setTrace(1);
log0("6502 paused...\n");
doCmdAddr();
} }
void (*cmdFuncs[NUMCMDS])(char *params) = { void (*cmdFuncs[NUMCMDS])(char *params) = {
doCmdHelp, doCmdHelp,
doCmdReset, doCmdReset,
doCmdBreak, doCmdInterrupt,
doCmdContinue,
doCmdAddr, doCmdAddr,
doCmdStep, doCmdStep,
doCmdTrace, doCmdTrace,
doCmdBList, doCmdBList,
doCmdBSet, doCmdBreak,
doCmdBClear doCmdBClear,
doCmdContinue
}; };

View File

@@ -185,11 +185,9 @@ void Serial_Init(const uint32_t BaudRate0,
cls(0); cls(0);
cls(1); cls(1);
log0("stdio initialised\n"); // log0("stdio initialised\n");
log0("compiled at %s on %s\n",__TIME__,__DATE__); // log0("SerialPort0\n");
// log1("SerialPort1\n");
log0("SerialPort0\n");
log1("SerialPort1\n");
} }
#ifdef USE_HEXDUMP #ifdef USE_HEXDUMP

View File

@@ -77,7 +77,21 @@ architecture behavioral of AtomBusMon is
signal step : std_logic; signal step : std_logic;
signal step1 : std_logic; signal step1 : std_logic;
signal step2 : std_logic; signal step2 : std_logic;
signal brkpt_enable : std_logic;
signal brkpt_clock : std_logic;
signal brkpt_clock1 : std_logic;
signal brkpt_clock2 : std_logic;
signal brkpt_data : std_logic;
signal brkpt_active : std_logic;
signal brkpt_active1 : std_logic;
signal brkpt_0 : std_logic_vector(15 downto 0);
signal brkpt_1 : std_logic_vector(15 downto 0);
signal brkpt_2 : std_logic_vector(15 downto 0);
signal brkpt_3 : std_logic_vector(15 downto 0);
signal brkpt_reg : std_logic_vector(63 downto 0);
begin begin
inst_dcm5 : entity work.DCM0 port map( inst_dcm5 : entity work.DCM0 port map(
@@ -125,11 +139,23 @@ begin
portaout(6) => lcd_db_out(6), portaout(6) => lcd_db_out(6),
portaout(7) => lcd_db_out(7), portaout(7) => lcd_db_out(7),
portbin => (others => '0'), portbin(0) => '0',
portbin(1) => '0',
portbin(2) => '0',
portbin(3) => '0',
portbin(4) => '0',
portbin(5) => '0',
portbin(6) => sw1,
portbin(7) => brkpt_active1,
portbout(0) => step, portbout(0) => step,
portbout(1) => single, portbout(1) => single,
portbout(2) => reset, portbout(2) => reset,
portbout(7 downto 3) => open, portbout(3) => brkpt_enable,
portbout(4) => brkpt_clock,
portbout(5) => brkpt_data,
portbout(6) => open,
portbout(7) => open,
portdin => addr_inst(7 downto 0), portdin => addr_inst(7 downto 0),
portdout => open, portdout => open,
@@ -149,9 +175,9 @@ begin
lcd_db <= lcd_db_out when lcd_rw_int = '0' else (others => 'Z'); lcd_db <= lcd_db_out when lcd_rw_int = '0' else (others => 'Z');
lcd_db_in <= lcd_db; lcd_db_in <= lcd_db;
led3 <= dy_counter(24); -- red led3 <= '0'; -- red
led6 <= dy_counter(24); -- red led6 <= '0'; -- red
led8 <= not sw1; -- green led8 <= not brkpt_active; -- green
nrst_avr <= nsw2; nrst_avr <= nsw2;
@@ -160,26 +186,46 @@ begin
dy_data(1) <= hex & "0000" & Addr(7 downto 4); dy_data(1) <= hex & "0000" & Addr(7 downto 4);
dy_data(2) <= hex & "0000" & "00" & (not nsw2) & sw1; dy_data(2) <= hex & "0000" & "00" & (not nsw2) & sw1;
brkpt_0 <= brkpt_reg(15 downto 0);
brkpt_1 <= brkpt_reg(31 downto 16);
brkpt_2 <= brkpt_reg(47 downto 32);
brkpt_3 <= brkpt_reg(63 downto 48);
brkpt_active <= '1' when brkpt_enable = '1' and Sync = '1' and
((Addr = brkpt_0) or (Addr = brkpt_1) or (Addr = brkpt_2) or (Addr = brkpt_3))
else '0';
-- 6502 Control -- 6502 Control
syncProcess: process (Phi2) syncProcess: process (Phi2)
begin begin
if rising_edge(Phi2) then if rising_edge(Phi2) then
step1 <= step; -- Address monitoring
step2 <= step1;
if ((single = '0') or (step2 = '0' and step1 = '1')) then
Rdy <= '1';
else
Rdy <= not Sync;
end if;
addr_sync <= Addr; addr_sync <= Addr;
if (Sync = '1') then if (Sync = '1') then
addr_inst <= Addr; addr_inst <= Addr;
end if; end if;
-- Reset
if (reset = '1') then if (reset = '1') then
nRST <= '0'; nRST <= '0';
else else
nRST <= 'Z'; nRST <= 'Z';
end if; end if;
-- Breakpoints
brkpt_clock1 <= brkpt_clock;
brkpt_clock2 <= brkpt_clock1;
if (brkpt_enable = '0' and brkpt_clock2 = '0' and brkpt_clock1 = '1') then
brkpt_reg <= brkpt_data & brkpt_reg(63 downto 1);
end if;
brkpt_active1 <= brkpt_active;
-- Single Stepping
step1 <= step;
step2 <= step1;
if ((single = '0') or (step2 = '0' and step1 = '1')) then
Rdy <= (not brkpt_active);
else
Rdy <= (not Sync);
end if;
end if; end if;
end process; end process;