       goto tail_recurse;
     }
   }
+}
+
+Dura channel_advance_all_digital(Channel *cs, Dura d, Protocol *ps) {
+  Dura x = (Dura){0, 0};
+  for (int i = 0; i < DIG; i++) if (!cs[i].disabled) {
+    Dura y = channel_advance(cs+i, d, ps);
+    if (!dura_is_empty(y)) {
+      if (dura_is_empty(x) || lt_dura(y, x)) x = y;
+    }
+  }
+  x;
 }
 
 

        channel_pin_on(c, ps);
        started_yn = true;
        started_pq = true;
        c->runlevel = 3;
        c->pq = ps[c->who].q;
        c->yn = ps[c->who].s;
        c->e.nstim++;

  bool started_yn = false;
  bool started_pq = false;
tail_recurse:
  if (c->disabled || c->runlevel == C_ZZZ) return (Dura){0,0};
  if (c->runlevel == C_WAIT) {
    // Only relevant times are c->t and c->yn
    bool use_yn = lt_dura(c->yn, c->d);
    Dura *x = use_yn ? &(c->yn) : &(c->t);
