+}
+
+void avr_callback_sleep_raw(avr_t * avr, avr_cycle_count_t howLong)
+{
+ uint32_t usec = avr_pending_sleep_usec(avr, howLong);
+ if (usec > 0) {
+ usleep(usec);
+ }
+}
+
+void avr_callback_run_raw(avr_t * avr)
+{
+ avr_flashaddr_t new_pc = avr->pc;
+
+ if (avr->state == cpu_Running) {
+ new_pc = avr_run_one(avr);
+#if CONFIG_SIMAVR_TRACE
+ avr_dump_state(avr);
+#endif
+ }
+
+ // 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);