[comp.sys.atari.st] A replacement for Alcyon's signal function

RDROYA01@ULKYVX.BITNET (Robert Royar) (12/19/86)

I couldn't get the Alcyon signal function to work properly, and when I
traced through it I discovered that it still calls the bdos set exception
function which worked on cp/m68k systems, but apparently not on the ST.
So I wrote a new signal to replace the old one.  And since the ST has
a few more options than vanilla cp/m68k, I added some additional signals.
You can use this to set a trap for CNTRL-C, but be advised that you'll
have to write your own error handler, and it's probably best to check and
save the old value before you set it.  (Just like the original signal, this
function does not save the old vectors for you.)  BTW the way cp/m68k handled
the setting of exceptions (unless you used a bios call) was to fiddle with
a structure of the following type passed in d1
struct epb {
       int vecnum;
       long newvec;   /* supplied by the caller */
       long oldvec;   /*filled in by the bdos */
};

And now a question.  The bdos calls (trap #2) do not seem to be documented
anywhere.  Some are identical to cp/m68k calls, but others are in no way
the same.  Does anyone have a list of the functions and what they do?

--------------------------------- cut - here --------------------------
/* SIGNAL.C
 * From: RDROYA01@ULKYVX.BITNET (Robert Royar)
 * File to replace the nonworking Alcyon (GEMLIB) signal function.
 * Note the additional functions available.
 * Returns -1 on error, 0 on success, and 1 for an ignored signal.
 */

#include <osbind.h>
/* Here are the defs if your kit didn't have signal.h */
#ifdef  SIG_NO_INC
#define NSIG    15                      /* 15 simulated signals             */
#define SIGHUP   1                      /* Hangup                           */
#define SIGINT   2                      /* Interrupt (^C)                   */
#define SIGQUIT  3                      /* Quit signal                      */
#define SIGILL   4                      /* Illegal Instruction trap         */
#define SIGTRAP  5                      /* Trace Trap                       */
#define SIGIOT   6                      /* IOT instruction (on PDP-11)      */
#define SIGEMT   7                      /* EMT instruction (TRAP on 68k)    */
#define SIGFPE   8                      /* Floating point exception         */
#define SIGKILL  9                      /* Kill (cannot be intercepted)     */
#define SIGBUS  10                      /* BUSERR (non-ex memory reference) */
#define SIGSEGV 11                      /* Segmentation (MMU) violation     */
#define SIGSYS  12                      /* Bad argument to system call      */
#define SIGPIPE 13                      /* Write on a broken pipe           */
#define SIGALRM 14                      /* Alarm clock (what a name!)       */
#define SIGTERM 15                      /* Software termination signal      */
                                        /************************************/
#define BADSIG  (-1)                    /* Error return                     */
#define SIG_DFL (0)                     /* Default action on signal call    */
#define SIG_IGN (1)                     /* Ignore                           */
                                        /************************************/
#else
#include <signal.h>
#endif

#define NULL    0
#define TIM_INT 0x100
#define ERR_INT 0x101
#define CTRL_C  0x102
#define BUSERR  2       /* nonexistent memory */
#define ADDRERR 3       /* allignment violation */
#define ZERO_D  5       /* division by zero */
#define CHK     6       /* CHK interrupt */
#define TRAPV   7       /* overflow */
#define TRAP_0  32      /* TRAP #0 vector */
#define TRAP_3  35      /* TRAP #3 vector */
#define TRAP_12 44      /* TRAP #12 vector */
#define TRAP_15 47      /* TRAP #15 vector */

signal(sig, func)
register int sig;
register long func;
{
        int signum[16];
        register int *sigptr;
        register int i;

        sigptr = &signum[0];
        if (sig < 1 || sig > NSIG)
                return(BADSIG);
        switch(sig)
                {
                case SIGHUP:
                        Mfpint(1,func);
                        return(SIG_DFL);
                case SIGINT:
                case SIGQUIT:
                case SIGTERM:
                        /* WARNING: may close all open files */
                        *sigptr++ = CTRL_C;;
                        *sigptr = NULL;
                        break;
                case SIGILL:
                        *sigptr++ = 4; /* Illegal */
                        *sigptr++ = 8; /* Priv. */
                        *sigptr++ = 10; /* Line A !!WARNING!! */
                        *sigptr++ = 11; /* Line F !!WARNING!! */
                        *sigptr = NULL;
                        break;
                case SIGTRAP:
                        *sigptr++ = 9;  /* Trace */
                        *sigptr = NULL;
                        break;
                case SIGIOT:
                case SIGEMT:
                        *sigptr++ = TRAP_0;     /* TRAP 0 */
                        for (i=TRAP_3;i<=TRAP_12;*sigptr++ = i,++i)
                                ;
                        *sigptr++ = TRAP_15;
                        *sigptr = NULL;
                        break;
                case SIGFPE:
                        for (i=ZERO_D; i<=TRAPV;*sigptr++ = i,++i)
                                ;
                        *sigptr = NULL;
                        break;
                case SIGKILL:   /* ignored on the ST */
                        return(SIG_IGN); /* SIG_IGN = 1 */
                case SIGBUS:
                        *sigptr++ = BUSERR;
                        *sigptr = NULL;
                        break;
                case SIGSEGV:
                        *sigptr++ = ADDRERR;
                        *sigptr = NULL;
                        break;
                case SIGSYS:
                case SIGPIPE:
                        *sigptr++ = ERR_INT;    /* Is this OK? */
                        *sigptr = NULL;
                        break;
                case SIGALRM:
                        *sigptr++ = TIM_INT;
                        *sigptr = NULL;
                        break;
                }
        for(sigptr = &signum[0]; *sigptr != NULL; sigptr++)
                Setexc(*sigptr,func);
        return(SIG_DFL);
}