+ // if we just re-enabled the interrupts...
+ // double buffer the I flag, to detect that edge
+ if (avr->sreg[S_I] && !avr->i_shadow)
+ avr->interrupts.pending_wait++;
+ avr->i_shadow = avr->sreg[S_I];
+
+ // run the cycle timers, get the suggested sleep time
+ // until the next timer is due
+ avr_cycle_count_t sleep = avr_cycle_timer_process(avr);
+
+ avr->pc = new_pc;
+
+ if (avr->state == cpu_Sleeping) {
+ if (!avr->sreg[S_I]) {
+ if (avr->log)
+ printf("simavr: sleeping with interrupts off, quitting gracefully\n");
+ avr->state = cpu_Done;
+ return;
+ }
+ /*
+ * try to sleep for as long as we can (?)
+ */
+ avr->sleep(avr, sleep);
+ avr->cycle += 1 + sleep;
+ }
+ // Interrupt servicing might change the PC too, during 'sleep'
+ if (avr->state == cpu_Running || avr->state == cpu_Sleeping)
+ avr_service_interrupts(avr);
+}
+
+
+int avr_run(avr_t * avr)
+{
+ avr->run(avr);