   }
 }
 
+Protocol* process_ensure_protocol(byte ch) {
+  Channel *c = process_get_channel(ch);
+  if (c->who != 255) return protocols + c->who;
+  else if (c->zero != 255) {
+    c->refresh(protocols);
+    return protocols + c->who;
+  }
+  else if (proti < PROT) {
+    c->zero = proti;
+    c->who = c->zero;
+    protocols[proti].init();
+    proti++;
+    return protocols + c->who;
+  }
+  else return process_get_protocol(ch);   // Defer to get for error handling
+}
+
+Protocol* process_new_protocol(byte ch) {
+  Channel *c = process_get_channel(ch);
+  if (proti < PROT) {
+    byte old = c->who;
+    while (c->who != 255) { old = c->who; c->who = protocols[c->who].next; }
+    protocols[old].next = (byte)proti;
+    c->who = (byte)proti;
+    protocols[proti].init();
+    proti++;
+    return protocols + c->who;
+  }
+  else {
+    c->who = 255;
+    return process_get_protocol(ch);    // Defer to get for error handling
+  }
+}
+
 void process_reset() {
   Protocol::init(protocols, proti);
   Channel::init(channels);
   erri = 0;
+  alive = 0;
   runlevel = RUNSET;
 }
 
 void process_refresh() {
-  Channel::refresh(channels, protocols);
+  if (runlevel == RUNSTOP) {
+    Channel::refresh(channels, protocols);
+    runlevel = RUNSET;  
+  }
 }
 
 void process_start_running() {
-  // TODO - write me
+  go_go_go();
 }
 
 void process_start_running(byte who) {
-  // TODO - write me
+  if (who >= 'A' && who <= 'Z' && who != 'Y') {
+    int i = who - 'A';
+    if (who == 'Z') i -= 1;
+    Channel::solo(channels, i, protocols, proti);
+    process_start_running();
+  }
+  else {
+    char tiny[3]; tiny[0] = who; tiny[1] = '\n'; tiny[2] = 0;
+    error_with_message("Trying to run on unknown channel", tiny);
+  }
 }
 
 void process_stop_running(byte who) {
-  // TODO - write me
+  Channel *c = process_get_channel(who);
+  if (runlevel == GOGOGO) {
+    if (c->who != 255) {
+      c->pin_low();
+      c->runlevel = C_ZZZ;
+      c->who = 255;
+      if (alive > 0) alive -= 1;
+      if (alive == 0) runlevel = RUNSTOP;
+    }
+  }
 }
 
 void process_stop_running() {
-  // TODO - write me
+  for (int i = 0; i < DIG; i++) {
+    Channel *c = channels + i;
+    if (c->who != 255) {
+      c->pin_low();
+      c->runlevel = C_ZZZ;
+      c->who = 255;
+    }
+  }
+  alive = 0;
+  runlevel = RUNSTOP;
 }
 
 void process_say_the_time() {


#define ANALOG_ZERO 2047
#define ANALOG_AMPL 2047

#define CHAN (DIG+ANA)


    return true;
  }

  void solo(Protocol *ps, int &pi) {
    int i = 0;
    ps[i] = *this;
    while (i+1 < PROT && ps[i].next < PROT) {
      ps[i+1] = ps[ps[i].next];
      ps[i].next = (byte)(i+1);
      i++;
    }
    pi = i;
  }

  static void init(Protocol *ps, int &pi) {
    for (int i = 0; i < DIG+ANA; i++) ps[i].init();
    for (int i = DIG; i < DIG+ANA; i++) ps[i].j = 'l';
    pi = 0;
  }
};

Protocol protocols[PROT];
int proti = 0;
Protocol not_a_protocol = (Protocol){{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, ' ', ' ', 255, 255};


