Wie gesagt: noch Kleinkram dran zu machen.
Ähäm, naja ... Ich hab's mal im Rahmen der Möglichkeiten für einen Arduino-Uno "Arduinofiziert".
Es lebt tatsächlich, aber im wesentlichen von den Softwarefehlern.

Code:
/*
  #include "allpic.h"
  #pragma config = 0b000110000100  // hex-datei: fuses des 12F629
  #define EE_ROM      // eeprom nutzen
  #include "pic_mem.h"
  #include "timeloop.h"   // timer-routinen
*/

// PIC C-Compiler compatibility

typedef int8_t uns8; // stdint compatibility
typedef bool   BOOL;
#define FALSE  false
#define TRUE   false

/*
  #define IN_0    0 // GPIO-Eingänge
  #define IN_1    1 //
  #define IN_2    2 //
  #define IN_3    3 //
  #define OUT_0   4 // GPIO-Ausgänge
  #define OUT_1   5 //
*/

//** alle sensoren, aktoren, triebe und neuronen nach abstraktion gestaffelt ******
#define NUMBEROFNEURONS 30
uns8 zellen[NUMBEROFNEURONS];    // zellen im RAM anlegen

#define FIRE_REQ      7 // fire_req bit in der zelle
#define FIRE_LIMIT    10  // fire_limit

#define SENS_0        0 // spezialzellen definieren
#define SENS_1        1 // Sensoren
#define SENS_2        2
#define SENS_3        3
#define TIMER         4 // Timer-Zelle
#define HUNGER        5 // Hunger-Zelle
#define FIRST_NEURON  6 // davor nur read-only-zellen
#define AKT_0         (sizeof(zellen) - 2)
#define AKT_1         (sizeof(zellen) - 1)

//******* verbunden werden zellen mit vielen links (dendriten) *********
#define NO_LINK   -1
//#define MAX_LINKS (128 / sizeof(struct _link))// viele links im EEPROM
#define MAX_LINKS 32

struct _link {      // struktur eines EEPROM-links
  uns8 src;     // leerer link: src_zelle == NO_LINK
  uns8 dst;     // verbindet source- mit dest-zelle
  uns8 use;     // nützlichkeit dieses links
};

#define LINK_SRC 0
#define LINK_DST 1
#define LINK_USE 2
/*
uint8_t src;
uint8_t dst;
uint8_t use;
*/
// LINK-Zugriffe im PIC
// #define LINK_RD(a,m)  ee_read((a) + offsetof(struct _link,m))
// #define LINK_WR(a,m,v)  ee_write((a) + offsetof(struct _link,m),v)
_link Simulated_EEPROM[NUMBEROFNEURONS];

uns8 LINK_RD(uns8 address, uns8 component)
{
  uns8 value = 0;
  if (component == LINK_SRC) value = Simulated_EEPROM[address].src;
  if (component == LINK_DST) value = Simulated_EEPROM[address].dst;
  if (component == LINK_USE) value = Simulated_EEPROM[address].use;
  return value;
}

void LINK_WR(uns8 address, uns8 component, uns8 value)
{

  if (address < NUMBEROFNEURONS)
  {
    if (component == LINK_SRC) Simulated_EEPROM[address].src = value;
    if (component == LINK_DST) Simulated_EEPROM[address].dst = value;
    if (component == LINK_USE) Simulated_EEPROM[address].use = value;
  } else
  {
    Serial.print("Error: link address out of range "); Serial.println(address);
    delay(100);
  }
}

static uns8 rand_link = 0;  // randomize link

/*
  void gpio_out(uint8_t pin)
  {

  }
*/

uint16_t FSR; //pointer auf zelle
uint16_t INDF; // ?


static void gi_denke(void)  // die genesis
{
  uns8 zell_ind = 0, link=0, freeLink=0, buf=0;
  BOOL hit;
  do {              // Suche feuernde zellen
    rand_link++;    // randomize link
    FSR = zellen + zell_ind;  // pointer auf zelle

    /**** sensoren, aktoren und triebe sind besondere zellen *****/
    /*
        if (zell_ind <= SENS_3) { // Sensoren abfragen
          buf = _BV(zell_ind);  // bit-maske entwickeln
          if (GPIO & buf) {
            if (!(INDF.0)) INDF = FIRE_LIMIT + _BV(FIRE_REQ);
          }
          else INDF.0 = 0   // FIRE_REQ bearbeiten
          }       // nun die aktoren
        else if (zell_ind == AKT_0) GPIO.OUT_0 = INDF.FIRE_REQ;
        else if (zell_ind == AKT_1) GPIO.OUT_1 = INDF.FIRE_REQ;

        if (INDF.FIRE_REQ == FALSE) continue; // zelle möchte nicht feuern
    */
    /***** wenn zelle feuern will, verfolge die links *************/
    //    INDF.FIRE_REQ = FALSE;  // zelle möchte feuern

    INDF &= ~(1 << FIRE_REQ);
    freeLink = NO_LINK; link = 0; hit = FALSE;
    do {      // alle links durchsuchen
      rand_link++;    // randomize link
      buf = LINK_RD(link, LINK_SRC); // linkbyte lesen
      if (buf == NO_LINK) freeLink = link; // leeren link merken
      else if (buf == zell_ind) { // link gefunden
        FSR = zellen + LINK_RD(link, LINK_DST); // pointer auf dst-zelle lesen
        //if ((++INDF == FIRE_LIMIT) && (!(INDF.FIRE_REQ))) { // will dst feuern?
        if ((++INDF == FIRE_LIMIT) && (!(INDF & (1 << FIRE_REQ)))) { // will dst feuern?
          //INDF.FIRE_REQ = TRUE; // feuer_req schon mal vormerken
          INDF |= (1 << FIRE_REQ);
          buf = LINK_RD(link, LINK_USE); // zwei zellen feuern synchron
          LINK_WR(link, LINK_USE, ++buf); // dadurch wird der link nuetzlicher
          hit = TRUE;   // zumindest ein nützlicher link
        }
      }
      //link += sizeof(struct _link);// nächsten link adressieren
      link++;// the link pointer is only an address
    } while (link < MAX_LINKS);
    //while (link < MAX_LINKS * sizeof(struct _link));

    /** wenn kein nützlicher link gefunden und platz ist: erzeuge neuen link **/
    if ((!hit) && (freeLink != NO_LINK)) {
      LINK_WR(freeLink, LINK_SRC, zell_ind); // link neu erzeugen
      buf = rand_link % sizeof(zellen); // randomize verlinken, aber eingrenzen
      if (buf < FIRST_NEURON) buf += FIRST_NEURON;    // keine read-only-zellen
      if (buf == zell_ind) buf++; // zellen nicht direkt rückkoppeln
      LINK_WR(freeLink, LINK_DST, buf);
      LINK_WR(freeLink, LINK_USE, 0);  // ob der link nützlich wird, weiß keiner
    }
  } while (++zell_ind < sizeof(zellen)); // nächste zelle
}

#define DELETE    0
#define REDUCE    1
#define SLEEP   2

static void gi_links(uns8 steuer) // links abschwächen
{
  uns8 link = 0, buf;
  do {          // alle links durchsuchen
    if (LINK_RD(link, LINK_SRC) != NO_LINK) { // gelöschte ignorieren
      if (steuer == DELETE) buf = 0;
      else {
        buf = LINK_RD(link, LINK_USE); // nuetzlichkeit lesen
        if (buf) LINK_WR(link, LINK_USE, --buf); // langsam verlernen
      }
      if (!buf) LINK_WR(link, LINK_SRC, NO_LINK); // link ganz löschen
    }
    //link += sizeof(struct _link); // nächster link
    link++;
  } while (link < MAX_LINKS);
  //while (link < MAX_LINKS * sizeof(struct _link));
  if (steuer == DELETE) rand_link = 0;
}

static void gi_zellen(uns8 steuer)// zell-erregungen abschwächen
{
  uns8 zell_ind = 0;
  do {        // Suche zellen
    FSR = zellen + zell_ind;  // zellerregung lesen
    if (steuer == DELETE) INDF = 0;
    if (INDF) INDF--;
    if ((steuer == SLEEP) && (INDF > FIRE_LIMIT)) INDF = FIRE_LIMIT - 1;
  } while (++zell_ind < sizeof(zellen)); // nächste zelle
}

void showLinks(uint8_t adr)
{
  Serial.print(adr); Serial.print(" -");
  Serial.print(" src:"); Serial.print(Simulated_EEPROM[adr].src);
  Serial.print(" dst:"); Serial.print(Simulated_EEPROM[adr].dst);
  Serial.print(" use:"); Serial.print(Simulated_EEPROM[adr].use);
  Serial.println();
}

void showAll()
{
  Serial.println("list Neurons:");
  for (int n = 0; n < MAX_LINKS; n++)
  {
    showLinks(n);
  }
  Serial.println();
}

void setup()
{
  Serial.begin(115200);
  Serial.println("Gugi ;-)");
  delay(1000);
  gi_links(DELETE);   // alle links löschen
  gi_zellen(DELETE);    // zellerregungen löschen

}

uns8 loopCounter = 0;
//  FOREVER {
void loop()
{
  Serial.println("gi_denke");
  gi_denke();
  if (!++loopCounter) {
    Serial.println("gi_links");
    gi_links(REDUCE);   // links langsam verlernen
    Serial.println("gi_zellen");
    gi_zellen(SLEEP);   // schlafen
  }
  else if (!(loopCounter & 0x1F)) // alle 32 durchläufe
  {
    Serial.println("gi_zellen");
    gi_zellen(REDUCE);  // zellerregungen vermindern
    showAll();
    delay(1000);
  }
}