mirror of
https://github.com/hoglet67/AtomBusMon.git
synced 2025-08-15 15:27:23 +00:00
Added breakpoint functionality
Change-Id: I82b1162249a1bfed2d340361b205340dfbb70d86
This commit is contained in:
@@ -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
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@@ -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
|
||||||
|
@@ -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;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user