/************************************************************
 * WhatOS generated operating system                        *
 *                                                          *
 * File : source file                                       *
 * WhatOS version: 2.0.2                                    *
 * Time: Sat, 28 May 2005 20:19:55 EDT                      *
 ************************************************************/

#include "wossystem.h"

wuint16 wos_system_signature(void) { return 7230; }

/************************************************************
 * Simulation interface
 */
#define WOS_BLOCKNAME wos_block_simint
#define WOS_BLOCK_START
#include "wossystem.h"

#ifdef WOS_DBG_SIM

#define WOS_SIM_SIG_PRESENTED (0)
#define WOS_SIM_HOOK (1)

extern wuint16 wos_time_get();
extern void wos_sim_event(wuint8 type,
                          wuint8 source,
                          wuint8 dest,
                          wuint8 signame,
                          wuint16 sigsize,
                          void * sigvalue,
                          wuint8 alloc);

wuint8
wos_sim_mapsize(wuint8 sigid)
{
    static wuint8 const sizes [] = {
sizeof(packet), sizeof(packet), sizeof(wuint8), sizeof(wuint8), 0};
    return sizes[sigid];
}

wuint8
wos_sim_mapalloc(wuint8 sigid)
{
    static wuint8 const allocd [] = {1, 1, 0, 0, 0};
    return (allocd[sigid]);
}

/* -- hooks -- */

#define hook_hello(src, val)\
    wos_sim_event(WOS_SIM_HOOK,\
                  (src),\
                  WOS_ENVIRONMENT,\
                  0,\
                  sizeof(packet),\
                  (val),\
                  1)

#define hook_reply(src, val)\
    wos_sim_event(WOS_SIM_HOOK,\
                  (src),\
                  WOS_ENVIRONMENT,\
                  1,\
                  sizeof(packet),\
                  (val),\
                  1)

#define hook_sub_rx_byte(src, val)\
    wos_sim_event(WOS_SIM_HOOK,\
                  (src),\
                  WOS_ENVIRONMENT,\
                  2,\
                  sizeof(wuint8),\
                  (val),\
                  0)

#define hook_sub_tx_byte(src, val)\
    wos_sim_event(WOS_SIM_HOOK,\
                  (src),\
                  WOS_ENVIRONMENT,\
                  3,\
                  sizeof(wuint8),\
                  (val),\
                  0)

#define hook_sub_tx_rdy(src, val)\
    wos_sim_event(WOS_SIM_HOOK,\
                  (src),\
                  WOS_ENVIRONMENT,\
                  4,\
                  0,\
                  0,\
                  0)

#endif /* WOS_DBG_SIM */

#define wos_alloc_made_room_hook(t) wos_sq_reset()

#define WOS_BLOCK_END
#include "wossystem.h"

/************************************************************
 * SignalQ
 */

#define WOS_BLOCKNAME wos_block_signalq
#define WOS_BLOCK_START
#include "wossystem.h"

struct wos_Signal;

typedef struct wos_Task {
    wuint8 const id;
    wuint8 const group;
    wuint8 (* const function)(wuint8, void *);
    struct wos_Signal * sig;
    wuint16 await;
    void * resource;
    wuint8 priority;
    unsigned running : 1;
} wos_Task;

typedef struct wos_Signal {
    wuint8 id;
    struct wos_Task * destination;
    struct wos_Signal * next;
    void * value;
    wuint8 source;
    wuint8 requires;
} wos_Signal;

typedef struct {
    wos_Signal * head;
    wos_Signal * next;
} wos_SignalQ;

static wos_SignalQ wos_signalq;

void
wos_sq_clear()
{
    wos_signalq.head = 0;
    wos_signalq.next = 0;
}

#define wos_sq_reset() wos_signalq.next = wos_signalq.head

static wuint16 wos_busy_time_start;
static wuint16 wos_busy_time;
static wuint8 wos_busy;

#ifndef WOS_DBG_SIM
#ifndef wos_time_get
#define wos_time_get() 0
#endif
#endif

#define wos_busy_start()                        \
{                                               \
    wos_busy_time_start = wos_time_get();       \
    wos_busy = 1;                               \
}

#define wos_busy_end()                                          \
{                                                               \
    wos_busy = 0;                                               \
    wos_busy_time -= wos_busy_time_start - wos_time_get();      \
}

void
wos_sq_enqueue(wos_Signal * sig)
{
    wos_Signal * ps;
    wuint8 met_next;

    if (!wos_busy) {
        wos_busy_start();
    }

    /* empty queue */
    if (!wos_signalq.head) {
        wos_signalq.head = sig;
        wos_signalq.next = sig;
        sig->next = 0;
        return;
    }

    /* entry before first node */
    if (wos_signalq.head->destination->priority > sig->destination->priority) {
        sig->next = wos_signalq.head;
        wos_signalq.head = sig;
        wos_signalq.next = sig;
        return;
    }

    ps = wos_signalq.head;
    met_next = 0;
    for(;;) {
        if (ps == wos_signalq.next)
            met_next = 1;
        if (!ps->next)
            break;
        if (ps->next->destination->priority > sig->destination->priority)
            break;
        ps = ps->next;
    }
    sig->next = ps->next;
    ps->next = sig;
    if (!met_next)
        wos_signalq.next = sig;
}

#define wos_sq_read() wos_signalq.next

#define wos_sq_advance()\
{\
    ASSERT1(wos_signalq.next,\
            "wos_sq_advance: advance while pointing to nothing");\
    wos_signalq.next = wos_signalq.next->next;\
    if (!wos_signalq.next && wos_busy) wos_busy_end();\
}

void
wos_sq_remove(wos_Signal * s)
{
    wos_Signal *ps = wos_signalq.head;

    if (ps == s){               /* remove first */
        ASSERT1(wos_signalq.next == wos_signalq.head,
               "wos_sq_remove: disallowed removal");
        wos_signalq.head = ps->next;
        wos_signalq.next = wos_signalq.head;
    }
    else {                      /* remove else */
        wuint8 set_next = 0;

        for(;;) {
            if (!set_next) {
                if (ps == wos_signalq.next) {
                    set_next = 1;
                }

                if (ps->destination == s->destination) {
                    wos_signalq.next = ps;
                    set_next = 1;
                }
            }

            if (ps->next == s) {
                break;
            }

            ps = ps->next;
        }

        ps->next = s->next;

        if (!set_next) {
            ASSERT1(wos_signalq.next == s,
                   "wos_sq_remove: disallowed removal");
            wos_signalq.next = s->next;
        }
    }
    if (!wos_signalq.next && wos_busy) wos_busy_end();
}

#if WOS_TRACE_ON(WOS_BLOCKNAME)
void
wos_sq_print()
{
    wos_Signal *ps = wos_signalq.head;

    TRACE1("signalq:");
    if (!ps) {
        TRACE1("  empty");
        return;
    }

    while (ps) {
        if (ps == wos_signalq.next) {
            TRACE3("  signal %i(%i) *next*",
                   ps->id, ps->destination->priority);
        }
        else
            TRACE3("  signal %i(%i)",
                   ps->id, ps->destination->priority);
        ps=ps->next;
    }
}
#endif

#define WOS_BLOCK_END
#include "wossystem.h"

/************************************************************
 * Process
 */
#define WOS_BLOCKNAME wos_block_process
#define WOS_BLOCK_START
#include "wossystem.h"

#ifndef WOS_DBG_SIM
#define wos_sim_event(type, source, dest, signame, sigsize, sigvalue, alloc) {}
#define wos_sim_mapsize(sigid) {}
#define wos_sim_mapalloc(sigid) {}
#endif /* WOS_DBG_SIM */

#define WOS_NUM_TASKS 3
#define WOS_NUM_SIGNALS 5

static wuint8 wos_tgroups_running;


wuint8 csliprx(wuint8 input, void * inputval);
#define wos_task_csliprx (wos_tasks[0])
#define wos_task_id_csliprx (0)

wuint8 csliptx(wuint8 input, void * inputval);
#define wos_task_csliptx (wos_tasks[1])
#define wos_task_id_csliptx (1)

wuint8 hello_whatos(wuint8 input, void * inputval);
#define wos_task_hello_whatos (wos_tasks[2])
#define wos_task_id_hello_whatos (2)

static wos_Task wos_tasks[] = {
    {0, 0, &csliprx, (wos_Signal *) 0, -1, (void *) 0, 64, 0},
    {1, 0, &csliptx, (wos_Signal *) 0, -1, (void *) 0, 64, 0},
    {2, 0, &hello_whatos, (wos_Signal *) 0, -1, (void *) 0, 64, 0}};

void
wos_proc_init()
{
    wuint8 i;

    wos_tgroups_running = 0;

    for (i = 0; i < WOS_NUM_TASKS; i++) {
        wos_tasks[i].running = 0;
        wos_tasks[i].sig = 0;
        wos_tasks[i].await = -1;
        wos_tasks[i].resource = 0;
    }
}

#define accept() return(1)
#define reject() return(2)

static wuint16 const wos_sigmasks[WOS_NUM_SIGNALS];
void *wos_alloc_acquire(wuint8);
void wos_alloc_release(void*);

#ifndef wos_periodic
#define wos_periodic() {}
#endif

#ifndef WOS_DBG_SIM
#ifndef wos_time_get
#define wos_time_get() 0
#endif
#endif

static wuint16 wos_periodic_time_start;
static wuint16 wos_periodic_time_max;
static wuint8 wos_periodic_task_max;

void
wos_process(wuint8 forever)
{
    static wos_Signal *s;
    wos_Task * t;
    wuint8 ret;

    for(;;) {
        t = 0;
        s = wos_sq_read();
        if (!s) {
            if (!forever)
                break;
            else
                goto wos_check_periodic;
        }

        t = s->destination;
        if ((t->group & wos_tgroups_running) || t->running) {
            break;
        }

        if (s->requires != 255) {
            t->resource = wos_alloc_acquire(s->requires);
            if (!t->resource) {
                wos_sq_advance();
                continue;
            }
            s->requires = 255;
        }

        else if (!(t->await & wos_sigmasks[s->id])) {
            wos_sq_advance();
            continue;
        }

        wos_sim_event(WOS_SIM_SIG_PRESENTED,
                      s->source,
                      t->id,
                      s->id,
                      wos_sim_mapsize(s->id),
                      s->value,
                      wos_sim_mapalloc(s->id));
        t->sig = s;
        t->running = 1;
        wos_tgroups_running |= t->group;
        ret = t->function(t->sig->id, t->sig->value);
        t->running = 0;
        wos_tgroups_running &= ~t->group;
        ASSERT1((ret == 1) || (ret == 2),
               "task did not exit with accept/reject");
        if (ret == 1) {
            wos_sq_remove(t->sig);
            wos_alloc_release(t->sig);
        }
        else if (t->sig == wos_sq_read())
            wos_sq_advance();

wos_check_periodic:
        {
            wuint16 now = wos_time_get();
            if (now - wos_periodic_time_start > wos_periodic_time_max) {
                wos_periodic_time_max = now - wos_periodic_time_start;
                if (t)
                    wos_periodic_task_max = t->id;
                else
                    wos_periodic_task_max = -1;
            }
            wos_periodic_time_start = now;
            wos_periodic();
        }
    }
}

#define WOS_BLOCK_END
#include "wossystem.h"
/************************************************************
 * Allocator
 */
#define WOS_BLOCKNAME wos_block_alloc
#define WOS_BLOCK_START
#include "wossystem.h"

#define wos_alloc_num_types (2)
#define wos_alloc_type_packet (0)
#define wos_alloc_num_blocks_packet (2)
#define wos_alloc_block_size_packet (sizeof(packet) + 2)

static wuint8 wos_alloc_blocks_packet[wos_alloc_num_blocks_packet * wos_alloc_block_size_packet];
#define wos_alloc_type_wos_Signal (1)
#define wos_alloc_num_blocks_wos_Signal (10)
#define wos_alloc_block_size_wos_Signal (sizeof(wos_Signal) + 2)

static wuint8 wos_alloc_blocks_wos_Signal[wos_alloc_num_blocks_wos_Signal * wos_alloc_block_size_wos_Signal];

typedef struct {
    wuint8 * const blocks;
    wuint8 const num_blocks;
    wuint8 const block_size;
    wuint8 count;
    wuint8 max_count;
    wuint8 fail_count;
    unsigned failed : 1;
} wos_FreeList;


static wos_FreeList wos_alloc_freelists[] = {
    {wos_alloc_blocks_packet, wos_alloc_num_blocks_packet, wos_alloc_block_size_packet},
    {wos_alloc_blocks_wos_Signal, wos_alloc_num_blocks_wos_Signal, wos_alloc_block_size_wos_Signal}
};

void
wos_alloc_init()
{
    wuint8 i;
    wos_FreeList * fl;
    wuint8 *p;
    for (i = 0; i < wos_alloc_num_types; i++) {
        fl = wos_alloc_freelists + i;
        fl->count =0;
        fl->max_count = 0;
        fl->fail_count = 0;
        fl->failed = 0;
        for (p = fl->blocks;
             p < fl->blocks + (fl->num_blocks * fl->block_size);
             p += fl->block_size) {
            p[0] = 0;           /* refs */
            p[1] = i;           /* freelist id */
        }
    }
}


void *
wos_alloc_acquire(wuint8 typeid)
{
    wos_FreeList * fl;
    wuint8 *p;
    fl = wos_alloc_freelists + typeid;

    if (fl->count == fl->num_blocks) {
        fl->failed = 1;
        if (fl->fail_count < 255)
            fl->fail_count++;
        TRACE2("no room to acquire type %i", typeid);
    }
    else {
        for (p = fl->blocks;
             (p < fl->blocks + (fl->num_blocks * fl->block_size));
             p += fl->block_size) {
            if (!p[0]) {
                p[0] = 1;
                fl->count ++;
                if (fl->count > fl->max_count) {
                    fl->max_count = fl->count;
                }
                TRACE3("acquired type %i, fl->count = %i",
                      typeid, fl->count);
                return (p + 2);
            }
        }
    }
    return 0;
}

void
wos_alloc_reference(void *b)
{
    wuint8 *p = (wuint8 *)b;

    p[-2]++;
    TRACE4("referenced type %i, refs = %i, fl->count = %i",
          p[-1], p[-2], wos_alloc_freelists[p[-1]].count);
}

void
wos_alloc_release(void *b)
{
    wos_FreeList * fl;
    wuint8 *p = (wuint8 *)b;

    p[-2]--;
    if (!p[-2]) {
        fl = wos_alloc_freelists + p[-1];
        fl->count--;
        if (fl->failed) {
            fl->failed = 0;
            TRACE2("made room for type %i", (p[-1]));
            wos_alloc_made_room_hook(p[-1]);
        }
    }

    TRACE4("released type %i, refs = %i, fl->count = %i",
          p[-1], p[-2], wos_alloc_freelists[p[-1]].count);
}

#if WOS_TRACE_ON(WOS_BLOCKNAME)
void
wos_alloc_print_statistics()
{
    wos_FreeList * fl;
    TRACE1("allocator statistics:");
    for (fl = wos_alloc_freelists;
         fl < wos_alloc_freelists + wos_alloc_num_types; fl++) {
        TRACE1("  freelist:");
        TRACE2("    count = %i", fl->count);
        TRACE2("    max_count = %i", fl->max_count);
        TRACE2("    fail_count = %i", fl->fail_count);
    }
}
#endif
#define WOS_BLOCK_END
#include "wossystem.h"

/************************************************************
 * NetTypes -- packing and unpacking support
 */
#define WOS_BLOCKNAME wos_block_types
#define WOS_BLOCK_START
#include "wossystem.h"

#include <stdarg.h>
#include <string.h>


#define WOS_GET_ARG(TYPE, VTYPE)                \
{                                               \
    TYPE t = (TYPE) va_arg(args, VTYPE);        \
    arg = (char *) &t;                          \
    size = sizeof(TYPE);                        \
    break;                                      \
}

#ifdef WOS_TEST_FAIL
#define FAIL(c, msg)                            \
if (!(c)) {                                     \
    ASSERT1(0, msg);                            \
    return -1;                                  \
}
#else
#define FAIL(c, msg) {}
#endif /* WOS_TEST_FAIL */

wint
wos_net_pack (const wchar* format, wchar* buffer,
              const wuint len, ...)
{
    va_list args;
    wuint n = 0;
    wchar* p = (wchar*) format;
    wuint mult = 0;
    wuint size = 0;
    char * arg;

    FAIL(format, "no format");
    FAIL(buffer, "no buffer");
    FAIL(len, "no buffer length");

    va_start (args, len);

    for (; *p; ++p) {
        switch (*p) {
        case 'b': WOS_GET_ARG(wint8, int);
        case 'B': WOS_GET_ARG(wuint8, unsigned int);
        case 'h': WOS_GET_ARG(wint16, int);
        case 'H': WOS_GET_ARG(wuint16, unsigned int);
        case 'i': WOS_GET_ARG(wint32, wint32);
        case 'I': WOS_GET_ARG(wuint32, wuint32);
        case 's': {
            wchar* s;

            s = va_arg (args, wchar*);
            FAIL(s, "void * for string argument");

            FAIL(mult, "string without multiplier");
            FAIL(n + mult <= len, "buffer too small");

            memcpy (buffer, s, mult);
            buffer += mult;
            n += mult;
            mult = 0;
            break;
        }

        case '0':  case '1': case '2': case '3': case '4':
        case '5':  case '6': case '7': case '8': case '9': {
            mult *= 10;
            mult += (*p - '0');
            break;
        }

        default: FAIL(0, "invalid format character");
        }

        if (size) {
            wuint i;
            FAIL(n + size <= len, "buffer too small");
            for (mult=(mult?mult:1); mult; --mult) {
                for (i = 0; i < size; i++) {
# if (WOS_BYTE_ORDER == WOS_LITTLE_ENDIAN)
                    *buffer++ = arg[size - 1 - i];
# else
                    *buffer++ = arg[i];
# endif
                }
            }
            n += size;
            size = 0;
        }
    }

    va_end (args);
    return n;
}

#undef WOS_GET_ARG

#define WOS_GET_ARG(TYPE)                       \
{                                               \
    TYPE *t = (TYPE*) va_arg(args, TYPE *);     \
    arg = (char *) t;                           \
    size = sizeof(TYPE);                        \
    break;                                      \
}

wint
wos_net_unpack (const wchar* format, wchar* buffer,
                wuint len, ...)
{
    va_list args;
    wuint n = 0;
    wchar* p = (wchar*) format;
    wuint mult = 0;
    wuint size = 0;
    char * arg;

    FAIL(format, "no format");
    FAIL(buffer, "no buffer");
    FAIL(len, "no buffer length");

    va_start (args, len);

    for (; *p; ++p) {
        switch (*p) {

        case 'b': WOS_GET_ARG(wint8);
        case 'B': WOS_GET_ARG(wuint8);
        case 'h': WOS_GET_ARG(wint16);
        case 'H': WOS_GET_ARG(wuint16);
        case 'i': WOS_GET_ARG(wint32);
        case 'I': WOS_GET_ARG(wuint32);
        case 's': {
            wchar* sp;

            sp = va_arg (args, wchar*);
            FAIL(sp, "void * for string argument");

            FAIL(mult, "string without multiplier");
            FAIL(n + mult <= len, "buffer too small");

            memcpy(sp, buffer, mult);
            buffer += mult;
            n += mult;
            mult = 0;
            break;
        }

        case '0':  case '1': case '2': case '3': case '4':
        case '5':  case '6': case '7': case '8': case '9': {
            mult *= 10;
            mult += (*p - '0');
            break;
        }

        default: FAIL(0, "invalid format character");
        }

        if (size) {
            wuint i;
            FAIL(n + size <= len, "buffer too small");
            for (mult=(mult?mult:1); mult; --mult) {
                for (i = 0; i < size; i++) {
# if (WOS_BYTE_ORDER == WOS_LITTLE_ENDIAN)
                    arg[size - 1 - i] = *buffer++;
# else
                    arg[i] = *buffer++;
# endif
                }
            }
            n += size;
            size = 0;
        }

    }

    va_end (args);
    return n;
}

#undef WOS_GET_ARG
#undef FAIL

/****************************************
 * Packers / Unpackers
 */

/* -- packet -- */

typedef struct {
    wuint8 wos_elem_0;
    wuint8 wos_elem_1[16];
} wos_elems_packet;

#define wos_pack_packet(b, buflen, v)\
    wos_net_pack("B16s", (b), (buflen),\
        ((wos_elems_packet *)(v))->wos_elem_0,\
        ((wos_elems_packet *)(v))->wos_elem_1)

#define wos_unpack_packet(v, b, buflen)\
    wos_net_unpack("B16s", (b), (buflen),\
        &((wos_elems_packet *)(v))->wos_elem_0,\
        ((wos_elems_packet *)(v))->wos_elem_1)

/* -- wuint8 -- */

typedef struct {
    wuint8 wos_elem_0;
} wos_elems_wuint8;

#define wos_pack_wuint8(b, buflen, v)\
    wos_net_pack("B", (b), (buflen),\
        ((wos_elems_wuint8 *)(v))->wos_elem_0)

#define wos_unpack_wuint8(v, b, buflen)\
    wos_net_unpack("B", (b), (buflen),\
        &((wos_elems_wuint8 *)(v))->wos_elem_0)
#define WOS_BLOCK_END
#include "wossystem.h"

/************************************************************
 * Glue
 */
#define WOS_BLOCKNAME wos_block_glue
#define WOS_BLOCK_START
#include "wossystem.h"

/*** common task interface ***/

#define WOS_TRACEE(m) emit(wos_tracee, (wos_task_id << 8) + (m))
#define WOS_ASSERTE(c, m) if (!(c)) emit(wos_asserte, (wos_task_id << 8) + (m))
#define WOS_MTRACEE(m) emit(wos_tracee, ((wos_task_id | 0x80) << 8) + (m))
#define WOS_MASSERTE(c, m) if (!(c)) emit(wos_asserte, ((wos_task_id | 0x80) << 8) + (m))

#define await(mask) wos_tasks[wos_task_id].await = (mask)
#define emit(signame, sigval) wos_emit_##signame(sigval)

#define acquire(t) wos_acquire_(wos_task_id, (t))
#define release(p) wos_alloc_release((void *)p)
#define reference(p) wos_alloc_reference((void *)p)
#define require(t) wos_tasks[wos_task_id].sig->requires = (t)

#define inputsrc wos_tasks[wos_task_id].sig->source

void
wos_interrupt(wuint8 wos_task_id)
{
    wint16 now;
    wos_Signal *this_sig;
    now = wos_time_get();
    if (now - wos_periodic_time_start > wos_periodic_time_max) {
        wos_periodic_time_max = now - wos_periodic_time_start;
        wos_periodic_task_max = wos_task_id;
    }
    wos_periodic_time_start = now;

    this_sig = wos_sq_read();
    wos_periodic();
    if (wos_sq_read() != this_sig) {
        wos_process(0);
    }
}

#define periodic() wos_interrupt(wos_task_id)

void *
wos_acquire_(wuint8 task_id, wuint8 type_id)
{
    void * r = wos_tasks[task_id].resource;
    if (r) {
        /* already allocated by the system */
        wos_tasks[task_id].resource = 0;
    }
    else {
        /* try to allocate */
        r = wos_alloc_acquire(type_id);
    }
    return r;
}

/*** system ***/

/* -- signal masks, default hooks, and emit -- */

#define wos_sigmask_hello (2)
#ifndef hook_hello
#define hook_hello(sigid, sigval) {}
#endif

#define wos_sigmask_reply (4)
#ifndef hook_reply
#define hook_reply(sigid, sigval) {}
#endif

#define wos_sigmask_sub_rx_byte (2)
#ifndef hook_sub_rx_byte
#define hook_sub_rx_byte(sigid, sigval) {}
#endif

#define wos_sigmask_sub_tx_byte (0)
#ifndef hook_sub_tx_byte
#define hook_sub_tx_byte(sigid, sigval) {}
#endif

#define wos_sigmask_sub_tx_rdy (2)
#ifndef hook_sub_tx_rdy
#define hook_sub_tx_rdy(sigid, sigval) {}
#endif

#if 2 > wos_alloc_num_types
#define WOS_NUM_LOST_SIGNALS (2 * 2)
#else
#define WOS_NUM_LOST_SIGNALS ((wos_alloc_num_types) * 2)
#endif

static wuint8 wos_lost_signals_buf[WOS_NUM_LOST_SIGNALS];
static wuint8 wos_lost_signals_i = 0;

static wuint16 const wos_sigmasks[] = {2,4,2,0,2};

void
wos_emit(wuint8 sigid, void * sigval, wuint8 source_taskid)
{
    static wuint8 const emit_table[] = {
        1, wos_task_id_hello_whatos,
        1, wos_task_id_csliptx,
        0, wos_task_id_csliprx,
        0,
        0, wos_task_id_csliptx
    };
    static wuint8 const sig_map[] = {0,2,4,6,7,9};
    wos_Signal *s;
    wuint8 const *p;
    wuint8 alloc;

    ASSERT1(sigid < 5, "signal not recognized");
    p = emit_table + sig_map[sigid];
    alloc = *p;

    p++;

    while (p < emit_table + sig_map[sigid+1]) {
        s = (wos_Signal *) wos_alloc_acquire(wos_alloc_type_wos_Signal);
        ASSERT1(s, "wos_emit : failed to allocate wos_Signal");
        if (!s) {
            if (wos_lost_signals_i < WOS_NUM_LOST_SIGNALS) {
                wos_lost_signals_buf[wos_lost_signals_i++] = sigid;
            }
            return;
        }
        s->id = sigid;
        s->value = sigval;
        s->source = source_taskid;
        s->destination = wos_tasks + (*p);
        s->requires = 255;
        if (alloc)
            wos_alloc_reference(sigval);
        wos_sq_enqueue(s);
        p++;
    }
    if (alloc)
        wos_alloc_release(sigval);
}

void
wos_init()
{
    wos_alloc_init();
    wos_proc_init();
    wos_sq_clear();
}

#define WOS_BLOCK_END
#include "wossystem.h"
/****************************************
 * Task csliprx
 */

#define WOS_BLOCKNAME csliprx
#define WOS_BLOCK_START
#include "wossystem.h"

#define wos_task_id (0)

/* -- allocated type ids and typedefs -- */
#define t_packet (wos_type_packet)

/* -- signals -- */
#define rx_packet (wos_sig_hello)
#define sub_rx_byte (wos_sig_sub_rx_byte)
#define m_sub_rx_byte (wos_sigmask_sub_rx_byte)
#define wos_emit_rx_packet(sigval) {\
    hook_hello(wos_task_id, (void *)((unsigned int)(sigval)));\
    wos_emit(rx_packet, (void *)((unsigned int)(sigval)), wos_task_id);\
}

/* -- defines -- */
#define END 192
#define ESC 219
#define ESC_END 220
#define ESC_ESC 221
#define OVERFLOW 1
#define PROTOCOL_VIOLATION 0
#define end (byte == END)
#define esc (byte == ESC)
#define esc_end (byte == ESC_END)
#define esc_esc (byte == ESC_ESC)
#define idle 2
#define receiving 0
#define receiving_esc 1
#define state_0 (newstate & 1)
#define state_1 (newstate & 2)
#define transition_code() if(state_0) {\
    if(state_1) {\
        {}\
    }\
    else {\
        if(esc_end) {\
            sm_receiving_esc_TO_receiving__end:\
            WOS_SM_TRACE("receiving_esc_TO_receiving__end");\
            byte = END;\
            goto receiving_esc_to_receiving;\
        }\
        else {\
            if(esc_esc) {\
                sm_receiving_esc_TO_receiving__esc:\
                WOS_SM_TRACE("receiving_esc_TO_receiving__esc");\
                byte = ESC;\
                receiving_esc_to_receiving:\
                newstate = receiving;\
                append:\
                if (p->len == sizeof(p->data)) {\
                    MTRACEE(OVERFLOW);\
                    release(p);\
                    newstate = idle;\
                    goto accept_it;\
                }\
                p->data[p->len] = byte;\
                p->len++;\
                accept_it:\
                state = newstate;\
                accept();\
            }\
            else {\
                sm_receiving_esc_TO_idle:\
                WOS_SM_TRACE("receiving_esc_TO_idle");\
                release(p);\
                newstate = idle;\
                goto accept_it;\
            }\
        }\
    }\
}\
else {\
    if(state_1) {\
        if(esc) {\
            sm_idle_TO_receiving_esc:\
            WOS_SM_TRACE("idle_TO_receiving_esc");\
            goto idle_to_receiving_esc;\
        }\
        else {\
            if(end) {\
                sm_idle_TO_idle:\
                WOS_SM_TRACE("idle_TO_idle");\
                goto accept_it;\
            }\
            else {\
                sm_idle_TO_receiving:\
                WOS_SM_TRACE("idle_TO_receiving");\
                idle_to_receiving_esc:\
                p = acquire(t_packet);\
                if (!p) {\
                    TRACE1("rejecting byte -- no room for packet");\
                    await(0);\
                    require(t_packet);\
                    reject();\
                }\
                p->len = 0;\
                if (byte == ESC) {\
                    newstate = receiving_esc;\
                    goto accept_it;\
                }\
                else {\
                    newstate = receiving;\
                    goto append;\
                }\
            }\
        }\
    }\
    else {\
        if(esc) {\
            sm_receiving_TO_receiving_esc:\
            WOS_SM_TRACE("receiving_TO_receiving_esc");\
            newstate = receiving_esc;\
            goto accept_it;\
        }\
        else {\
            if(end) {\
                sm_receiving_TO_idle:\
                WOS_SM_TRACE("receiving_TO_idle");\
                emit(rx_packet, p);\
                newstate = idle;\
                goto accept_it;\
            }\
            else {\
                sm_receiving_TO_receiving:\
                WOS_SM_TRACE("receiving_TO_receiving");\
                goto append;\
            }\
        }\
    }\
}\
WOS_SM_TRACE("none");

/* -- task external code */

/* -- process -- */
wuint8
csliprx(wuint8 input, void * inputval)
{
    static wuint8 state = idle;
    static packet * p;
    wuint8 byte;
    wuint8 newstate = state;

    byte = (wuint8) (unsigned int) inputval;
    await(-1);
    transition_code();
    reject();
}
/* -- undefine all defines to avoid warnings -- */
#define WOS_BLOCK_END
#include "wossystem.h"
#undef wos_task_id
#undef t_packet
#undef rx_packet
#undef sub_rx_byte
#undef m_sub_rx_byte
#undef wos_emit_rx_packet
#undef END
#undef ESC
#undef ESC_END
#undef ESC_ESC
#undef OVERFLOW
#undef PROTOCOL_VIOLATION
#undef end
#undef esc
#undef esc_end
#undef esc_esc
#undef idle
#undef receiving
#undef receiving_esc
#undef state_0
#undef state_1
#undef transition_code
/****************************************
 * Task csliptx
 */

#define WOS_BLOCKNAME csliptx
#define WOS_BLOCK_START
#include "wossystem.h"

#define wos_task_id (1)

/* -- allocated type ids and typedefs -- */
#define t_packet (wos_type_packet)

/* -- signals -- */
#define sub_tx_byte (wos_sig_sub_tx_byte)
#define sub_tx_rdy (wos_sig_sub_tx_rdy)
#define tx_packet (wos_sig_reply)
#define m_sub_tx_rdy (wos_sigmask_sub_tx_rdy)
#define m_tx_packet (wos_sigmask_reply)
#define wos_emit_sub_tx_byte(sigval) {\
    hook_sub_tx_byte(wos_task_id, (void *)((unsigned int)(sigval)));\
}

/* -- defines -- */
#define END 192
#define ESC 219
#define ESC_END 220
#define ESC_ESC 221
#define end p->data[i] == END
#define ending 1
#define esc p->data[i] == ESC
#define i_tx_rdy input == sub_tx_rdy
#define idle 0
#define left i < p->len
#define state_0 newstate & 1
#define state_1 newstate & 2
#define transition_code() if(i_tx_rdy) {\
    if(state_1) {\
        if(state_0) {\
            sm_tx_esc_TO_tx:\
            WOS_SM_TRACE("tx_esc_TO_tx");\
            newstate = tx;\
            if (esc) {\
                byte = ESC_ESC;\
            }\
            else {\
                byte = ESC_END;\
            }\
            i++;\
            goto emit_it;\
        }\
        else {\
            if(left) {\
                if(esc) {\
                    sm_tx_TO_tx_esc:\
                    WOS_SM_TRACE("tx_TO_tx_esc");\
                    newstate = tx_esc;\
                    byte = ESC;\
                    goto emit_it;\
                }\
                else {\
                    if(end) {\
                        goto sm_tx_TO_tx_esc;\
                    }\
                    else {\
                        sm_tx_TO_tx:\
                        WOS_SM_TRACE("tx_TO_tx");\
                        byte = p->data[i++];\
                        goto emit_it;\
                    }\
                }\
            }\
            else {\
                sm_tx_TO_ending:\
                WOS_SM_TRACE("tx_TO_ending");\
                newstate = ending;\
                release(p);\
                byte = END;\
                goto emit_it;\
            }\
        }\
    }\
    else {\
        if(state_0) {\
            sm_ending_TO_idle:\
            WOS_SM_TRACE("ending_TO_idle");\
            newstate = idle;\
            goto accept_it;\
        }\
        else {\
            {}\
        }\
    }\
}\
else {\
    if(state_1) {\
        {}\
    }\
    else {\
        if(state_0) {\
            {}\
        }\
        else {\
            sm_idle_TO_tx:\
            WOS_SM_TRACE("idle_TO_tx");\
            newstate = tx;\
            p = inputval;\
            i = 0;\
            byte = END;\
            \
            emit_it:\
            emit(sub_tx_byte, byte);\
            accept_it:\
            state = newstate;\
            accept();\
        }\
    }\
}\
WOS_SM_TRACE("none");
#define tx 2
#define tx_esc 3

/* -- task external code */

/* -- process -- */
wuint8
csliptx(wuint8 input, void * inputval)
{
    static wuint8 state = idle;
    static packet * p;
    static wuint8 i;
    wuint8 byte;
    wuint8 newstate = state;
    transition_code();
    reject();
}
/* -- undefine all defines to avoid warnings -- */
#define WOS_BLOCK_END
#include "wossystem.h"
#undef wos_task_id
#undef t_packet
#undef sub_tx_byte
#undef sub_tx_rdy
#undef tx_packet
#undef m_sub_tx_rdy
#undef m_tx_packet
#undef wos_emit_sub_tx_byte
#undef END
#undef ESC
#undef ESC_END
#undef ESC_ESC
#undef end
#undef ending
#undef esc
#undef i_tx_rdy
#undef idle
#undef left
#undef state_0
#undef state_1
#undef transition_code
#undef tx
#undef tx_esc
/****************************************
 * Task hello_whatos
 */

#define WOS_BLOCKNAME hello_whatos
#define WOS_BLOCK_START
#include "wossystem.h"

#define wos_task_id (2)

/* -- allocated type ids and typedefs -- */
#define t_packet (wos_type_packet)

/* -- signals -- */
#define hello (wos_sig_hello)
#define reply (wos_sig_reply)
#define m_hello (wos_sigmask_hello)
#define wos_emit_reply(sigval) {\
    hook_reply(wos_task_id, (void *)((unsigned int)(sigval)));\
    wos_emit(reply, (void *)((unsigned int)(sigval)), wos_task_id);\
}

/* -- defines -- */

/* -- task external code */

/* -- process -- */
wuint8
hello_whatos(wuint8 input, void * inputval)
{
    int i;
    packet * p = (packet *) inputval;
    for (i = 0; i < p->len; i++) {
        p->data[i+6] = p->data[i];
    }
    sprintf(p->data, "hello");
    p->data[5] = ' ';
    p->len = p->len + 6;
    emit(reply, p);
    accept();
}
/* -- undefine all defines to avoid warnings -- */
#define WOS_BLOCK_END
#include "wossystem.h"
#undef wos_task_id
#undef t_packet
#undef hello
#undef reply
#undef m_hello
#undef wos_emit_reply