A complete example

/*
 * XBRA example: install a handler using XBRA protocol into TOSs
 * timer handoff vector. Sit in a loop displaying a counter value
 * until any key is hit. Then remove the handler in a XBRA friendly
 * manner.
 *
 *      ++jrb    bammi@cadence.com
 */
#include <stddef.h>
#include <xbra.h>
#include <osbind.h>
#include <stdio.h>

unsigned short counter = 0;     /* counter incremented in handler */
unsigned short divisor = 50;    /* increment counter every divisor ticks */
void my_handler(void);
xbra_struct tick_xbra = _XBRA_INIT(my_handler); /* XBRA element */

#define _TIME_VEC       0x100

/*
 * our exception handler 
 */
void my_handler(void)
{
    if(--divisor == 0) 
    {
        counter++;  divisor = 50;
    }
    __asm__ volatile
    ("  unlk    a6                  /* clean up stack frame */
        movl    _tick_xbra+8, a0    /* jump to next handler */
        jmp     a0@");
}
        
/*
 * unlink a handler in a xbra friendly manner from the exc chain
 * returns 0 on clean unlink, !0 if something if it could'nt
 */
int unlink_handler(me, exc)
xbra_struct *me;
int exc;
{
    xbra_struct *this, *prev;
    long save_ssp;
    
    this = (xbra_struct *)      /* get head of chain */
        ((unsigned long)Setexc(exc, -1L) - offsetof(xbra_struct, jump));
    if(this == me)
    {   /* at the head, just unlink */
        Setexc(exc, me->next);
        return 0;
    }
    /* otherwise find me in the chain and unlink */
    save_ssp = Super(0L);
    for(prev = this; this && (this != me); prev = this,
        this = (xbra_struct *)((this->next) ?
                (((char *)(this->next)) - offsetof(xbra_struct, jump)) : 0))
    {
        /* validate the xbra */
        if(this->xbra_magic != _XBRA_MAGIC) 
        {       /* shame on you */
            Super(save_ssp);
            Setexc(exc, me->next); /* nuke it, otherwise it may call ME */
            return 1;              /* after I am deinstalled */
        }
    }
    
    if( (this == me) && (this->gnuc_magic == _GNUC_MAGIC) )
    {   /* unlink me from middle of the chain */
        prev->next = this->next;
        Super(save_ssp);
        return 0;
    }
    /* we are screwed */
    Super(save_ssp);
    return 2;
}

int main()
{
    char out[8];
    unsigned short last = 0xffff;

    /* install our handler */
    tick_xbra.next = (xptr) Setexc(_TIME_VEC, _XBRA_VEC(tick_xbra));

    /* continuously display counter until a key is hit */
    do {
        if(last != counter)
        {
            last = counter;
            sprintf(out, "%05u\r", last); /* display counter */
            Cconws(out);
        }
    } while( Bconstat(2) == 0 );

    /* remove the handler */
    return unlink_handler(&tick_xbra, _TIME_VEC);
}