   int s;  // Seconds
   int k;  // Clock ticks
 };
+
+bool dura_is_empty(Dura d) {
+  return d.s == 0 && d.k == 0;
+}
 
 bool valid_dura(Dura d) {
   return d.s >= 0 && d.k >= 0 && d.k < HTZ;

  int pm = (ce->pmiss > 999999 || ce->pmiss < 0) ? 999999 : ce->pmiss;
  int e0 = ce->emax0 / MHZ; e0 = (e0 > 99999 || e0 < 0) ? 99999 : e0;
  int e1 = ce->emax1 / MHZ; e1 = (e1 > 99999 || e1 < 0) ? 99999 : e1;
  int64_t t0 = dura_as_us(ce->toff0); t0 = (t0 > 9999999999ll || t0 < 0) ? 0 : t0;
  int64_t t1 = dura_as_us(ce->toff1); t1 = (t1 > 9999999999ll || t1 < 0) ? 0 : t1;
  snprintf(target, 60, "%09d%06d%09d%06d%05d%05d%10lld%10lld", ns, sm, np, pm, e0, e1, t0, t1);
}

#define C_ZZZ 0
#define C_OFF 1
#define C_STM 2
#define C_PLS 3

struct Channel {
  Dura t;         // Time remaining

      if (pq_first) {
        sub_duras(&(c->yn), c->pq);
        sub_duras(&(c->t), c->pq);
        if (c->runlevel == C_LO) {
          channel_pin_on(c, ps);
          started_pq = true;
          c->runlevel = C_HI;
          c->pq = ps[c->who].q;
          c->e.npuls++;
          // TODO--timing errors here!
        }
        else {
          channel_pin_off(c, ps);
          c->runlevel = C_LO;
          c->pq = ps[c->who].q;
          if (started_pq) { started_pq = false; c->e.pmiss++; }
        }
      }
      else if (yn_first) {
        sub_duras(&(c->t), c->pq);
        if (c->runlevel == C_HI) channel_pin_off(c, ps);
        c->runlevel = C_WAIT;
        c->yn = ps[c->who].z;
        if (started_pq) { started_pq = false; c->e.pmiss++; }
        if (started_yn) { started_yn = false; c->e.nmiss++; }
