diff --git a/simavr/sim/sim_avr.c b/simavr/sim/sim_avr.c index 6e43bf91f..d08b2ec77 100644 --- a/simavr/sim/sim_avr.c +++ b/simavr/sim/sim_avr.c @@ -282,6 +282,16 @@ avr_callback_sleep_gdb( ; } +static void +gracefully_quit( + avr_t * avr, + const char * reason) +{ + if (avr->log) + AVR_LOG(avr, LOG_TRACE, "simavr: %s, quitting gracefully\n", reason); + avr->state = cpu_Done; +} + void avr_callback_run_gdb( avr_t * avr) @@ -309,13 +319,16 @@ avr_callback_run_gdb( // until the next timer is due avr_cycle_count_t sleep = avr_cycle_timer_process(avr); + if (avr->state == cpu_Running && new_pc == avr->pc && avr->flash[new_pc] == 0xff && avr->flash[new_pc+1] == 0xcf && !avr->sreg[S_I]) { + gracefully_quit(avr, "rjmp .-2 with interrupts off"); + return; + } + avr->pc = new_pc; if (avr->state == cpu_Sleeping) { if (!avr->sreg[S_I]) { - if (avr->log) - AVR_LOG(avr, LOG_TRACE, "simavr: sleeping with interrupts off, quitting gracefully\n"); - avr->state = cpu_Done; + gracefully_quit(avr, "sleeping with interrupts off"); return; } /* @@ -372,13 +385,16 @@ avr_callback_run_raw( // until the next timer is due avr_cycle_count_t sleep = avr_cycle_timer_process(avr); + if (avr->state == cpu_Running && new_pc == avr->pc && avr->flash[new_pc] == 0xff && avr->flash[new_pc+1] == 0xcf && !avr->sreg[S_I]) { + gracefully_quit(avr, "rjmp .-2 with interrupts off"); + return; + } + avr->pc = new_pc; if (avr->state == cpu_Sleeping) { if (!avr->sreg[S_I]) { - if (avr->log) - AVR_LOG(avr, LOG_TRACE, "simavr: sleeping with interrupts off, quitting gracefully\n"); - avr->state = cpu_Done; + gracefully_quit(avr, "sleeping with interrupts off"); return; } /*