•  Back 
  •  BIOS 
  •  Index 
  •  Tree View 
  •  Cross references 
  •  %About 
  •  Show info about hypertext 
  •  View a new file 
Topic       : The ATARI Compendium
Author      : Scott Sanders / JAY Software
Version     : 1.25 (20/6/2003)
Subject     : Documentation
Nodes       : 1117
Index Size  : 32614
HCP-Version : 6
Compiled on : Atari
@charset    : UTF-8
@lang       : en
@default    : 
@help       : %About
@options    : +g -i -t4 +y +z
@width      : 100
View Ref-File
                              The XBRA Protocol


Many applications that add functionality to the system do so by 'hooking'
themselves into one or more interrupt or pass-through vectors (usually
with Setexc()). Most vector handlers work by executing the relevant code
when the interrupt is called and then calling the original vector handler.
When several applications handle one vector, a vector 'chain' is created.
This chain makes it difficult for debuggers or the process itself to
'unhook' itself from the chain.

The XBRA protocol was designed so that processes that wish to be able to
unhook themselves may and so that debuggers can trace the 'chain' of
vector handlers. Following the protocal is simple. Prior to the first
instruction of the vector handler, insert three longwords into the
application as follows:

   ∙ The longword 'XBRA' 0x58425241.

   ∙ Another longword containing the application 'cookie' ID (this is the
     same as that put into the cookie jar if applicable).

   ∙ A longword into which should be placed the address of the original
     handler.

The following code example shows how to correctly use the XBRA protocol
in a routine designed to supplement the 680x0 TRAP #1 vector (GEMDOS):

instl_trap1:
            move.l      #my_trap1,-(sp)
            move.w      #VEC_GEMDOS,-(sp)
            move.w      #Setexc,-(sp)
            trap        #13
            addq.l      #8,sp
            move.l      d0,old_handler
            rts

            DC.L        'XBRA'
            DC.L        'SDS1'                  ; Put your cookie here
old_handler DC.L        0

my_trap1:
            movem.l     d2-d7/a2-a6,-(sp)

            ;
            ; Your TRAP #1 handler goes here.
            ;

            movem.l     (sp)+,d2-d7/a2-a6
            move.l      old_handler,-(sp)       ; Fake a return
            rts                                 ; to old code.

The following 'C' function is an example of how to use the XBRA protocol
to unhook a vector handler from the XBRA chain. This function will only
work if all installed vector handlers follow the XBRA protocol. It takes
a Setexc() vector number and an XBRA application id cookie as a parameter.
It returns the address of the routine that was unhooked or 0L if
unsuccessful.

typedef struct xbra
{
    LONG    xbra_id;
    LONG    app_id;
    VOID    (*oldvec)();
} XBRA;

LONG
unhook_xbra( WORD vecnum, LONG app_id )
{
    XBRA *rx;
    LONG vecadr, *stepadr, lret = 0L;
    char *savessp;

    vecadr = Setexc( vecnum, VEC_INQUIRE );
    rx = (XBRA *)(vecadr - sizeof( XBRA ));

    /* Set supervisor mode for search just in case. */
    savessp = Super( SUP_SET );

    /* Special Case: Vector to remove is first in chain. */
    if( rx->xbra_id == 'XBRA' && rx->app_id == app_id )
    {
        Setexc( vecnum, rx->oldvec );
        return vecadr;
    }

    stepadr = (LONG *)&rx->oldvec;
    rx = (XBRA *)((LONG)rx->oldvec - sizeof( XBRA ));
    while( rx->xbra_id == 'XBRA' )
    {
        if( rx->app_id == app_id )
        {
            *stepadr = lret = (LONG)rx->oldvec;
            break;
        }

        stepadr = (LONG *)&rx->oldvec;
        rx = (XBRA *)((LONG)rx->oldvec - sizeof( XBRA ));
    }

    Super( savessp );
    return lret;
}