/* ------------------------------------------------------------------------ */
/*  @@ Source Documentation                         *** C Version ***       */
/*                                                                          */
/*  File : SBKBLST.C                                                        */
/*                                                                          */
/*  Description :                                                           */
/*      The program retrieves the BLASTER environment variable for          */
/*      the card settings. It does not perform any test on the              */
/*      hardware settings on the Card.                                      */
/*                                                                          */
/*  Copyright (c) Creative Technology Lte, 1993. All rights reserved.       */
/*                                                                          */
/* ------------------------------------------------------------------------ */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* Local functions */
int GetSetting (char *, int *, int);
void DisplaySetting(void);
int Asc2Int(char * ,int);

char *CardType[] = {
    "- Creative Sound Blaster Series -",
    "Sound Blaster",
    "Sound Blaster Pro",
    "Sound Blaster 2.0",
    "Sound Blaster Pro 2.0",
    "Sound Blaster Pro MCV",
    "Sound Blaster 16"
} ;

struct BLASTER {
    int cardid;         /* card type */
    int sbioaddx;       /* i/o address */
    int sbintr;         /* interrupt */
    int dma;            /* dma channel */
    int hdma;           /* high dma channel */
    int midi;           /* midi port */
    int mixer;          /* mixer port */
    int pbioaddx;       /* printer port (used only by Port Blaster) */
    int pbintr;         /* printer port interrupt */
} StBlst ;


main()
{
    char * blaster ;


    /* Initializes the BLASTER struct to null */
    memset (&StBlst,0,sizeof(StBlst)) ;

    if ((blaster = getenv("BLASTER")) != 0)
    {
        while (*blaster)
        {
            switch (*blaster)
            {
                case 'A' : /* Sound Blaster i/o address */
                      blaster ++ ;
                      /* Extracts the value set for each parameter in the
                         BLASTER environment */
                      blaster += GetSetting(blaster,&StBlst.sbioaddx,16) ;
                      break;

                case 'I' : /* Sound Blaster interrupt */
                      blaster ++ ;
                      blaster += GetSetting(blaster,&StBlst.sbintr,10) ;
                      break;

                case 'D' : /* DMA channel */
                      blaster ++ ;
                      blaster += GetSetting(blaster,&StBlst.dma,10) ;
                      break;

                case 'T' : /* Card type */
                      blaster ++ ;
                      blaster += GetSetting(blaster,&StBlst.cardid,10) ;
                      break;

                case 'M' : /* Mixer port */
                      blaster ++ ;
                      blaster += GetSetting(blaster,&StBlst.mixer,16) ;
                      break;

                case 'P' : /* Midi port */
                      blaster ++ ;
                      blaster += GetSetting(blaster,&StBlst.midi,16) ;
                      break;

                case 'H' : /* High DMA channel */
                      blaster ++ ;
                      blaster += GetSetting(blaster,&StBlst.hdma,10) ;
                      break;

                case 'L' :
                      blaster ++ ;
                      if (!strncmp(blaster,"PT:",3))
                      {
                          /* Port Blaster i/o address */
                          blaster += 3 ;
                          blaster += GetSetting(blaster,&StBlst.pbioaddx,10) ;
                      }
                      else if (!strncmp(blaster,"PI:",3))
                      {
                          /* Port Blaster interrupt */
                          blaster += 3 ;
                          blaster += GetSetting(blaster,&StBlst.pbintr,10) ;
                      }
                      break;
            }

            if (*blaster)
               blaster ++ ;
        }
        DisplaySetting() ; /* Displays the BLASTER environment */
    }
    else
        printf ("\nBLASTER environment not set.\n");

    return 0 ;
}


/* ------------------------------------------------------------------------ */
/*  @@ Usage                                                                */
/*                                                                          */
/*  int GetSetting (char *blaster, int *temp, int radix)                    */
/*                                                                          */
/*  Description :                                                           */
/*      Extracts individual parameter from the BLASTER environment.         */
/*                                                                          */
/*  Entry :                                                                 */
/*      blaster - pointer to the string of BLASTER environment              */
/*      temp    - pointer to the BLASTER structure                          */
/*      radix   - hexadecimal or decimal value                              */
/*                                                                          */
/*  Exit  :                                                                 */
/*      count   - the new offset of the pointer                             */
/*                                                                          */
/* ------------------------------------------------------------------------ */

int GetSetting(char * blaster, int * param, int radix)
{
    int count = 0 ;
    char temp[8] ;
    char *stop_at;

    while (*(blaster + count) != 0 && *(blaster + count) != ' ')
    {
        temp[count] = *(blaster + count) ;
        count ++ ;
    }
    temp[count] = 0 ;

    *param = (int)strtol(temp,&stop_at,radix) ;

    return (count) ;
}


/* ------------------------------------------------------------------------ */
/* @@ Usage                                                                 */
/*                                                                          */
/*  int Asc2Int(char * temp,int radix)                                      */
/*                                                                          */
/*  Description :                                                           */
/*      Converts numeric value in ASCII format to hexadecimal or decimal    */
/*      integer value.                                                      */
/*                                                                          */
/*  Entry :                                                                 */
/*      temp   - pointer to the ASCII string to be converted.               */
/*      radix  - spcifies HEXA (hexadecimal) or DECI (decimal) value.       */
/*                                                                          */
/*  Exit :                                                                  */
/*      converted - integer value in HEXA or DECI.                          */
/*                                                                          */
/* ------------------------------------------------------------------------ */

#define HEXA         16 /* hexadecimal value */
#define DECI         10 /* decimal value */
#define NUM          48 /* (base value of the numeric ASCII character) - 10 */
#define UCAP         55 /* (base value of the upper case character) - 10 */
#define LCAP         87 /* (base value of the lower case chraacter) - 10 */

int Asc2Int(char * temp,int radix)
{
    int NumOfDigit=0, digit, i ;
    int converted=0, value ;

    /* Total number of digit contains in the string */
    while (*(temp+NumOfDigit))
        NumOfDigit ++ ;

    /* Extracts the digit and converts to integer value */
    for (digit=0 ; digit<NumOfDigit ; digit++)
    {
        if (*(temp+digit) < 58)             /* numeric character (0 - 9) */
            value = *(temp + digit) - NUM ;
        else
            if (*(temp+digit) < 71)         /* upper case character (A - F) */
                value = *(temp + digit) - UCAP ;
            else
                if (*(temp+digit) < 103)    /* lower case character (a - f) */
                    value = *(temp + digit) - LCAP ;

        if (radix == HEXA)                  /* converts to hexadecimal value */
        {
            for (i=1; i<(NumOfDigit-digit); i++)
                value *= 16 ;
            converted += value ;
        }
        else if (radix == DECI)             /* converts to decimal value */
        {
            for (i=1; i<(NumOfDigit-digit); i++)
                value *= 10 ;
            converted += value ;
        }
    }
    return (converted) ;
}


/* ------------------------------------------------------------------------ */
/*  @@ Usage                                                                */
/*                                                                          */
/*  void DisplaySetting(void)                                               */
/*                                                                          */
/*  Description :                                                           */
/*      Displays the BLASTER enviroment accordingly.                        */
/*                                                                          */
/*  Entry :                                                                 */
/*      none                                                                */
/*                                                                          */
/*  Exit  :                                                                 */
/*      none                                                                */
/*                                                                          */
/*------------------------------------------------------------------------- */

void DisplaySetting()
{
    if (StBlst.cardid)
    {
        if (StBlst.cardid < 7 && StBlst.cardid > 0)
            printf ("\n%s card installed at\n",CardType[StBlst.cardid]) ;
        else
            printf ("\nUnknown card installed at\n");

        printf ("\tI/O port         : %x hex\n",StBlst.sbioaddx);
        printf ("\tInterrupt        : %d\n",StBlst.sbintr) ;
        printf ("\tDMA channel      : %d\n",StBlst.dma) ;
        if (StBlst.hdma)
            printf ("\tHigh DMA channel : %d\n",StBlst.hdma) ;
        if (StBlst.midi)
            printf ("\tMidi port        : %x hex\n",StBlst.midi);
        if (StBlst.mixer)
            printf ("\tMixer port       : %x hex\n",StBlst.mixer) ;
    }
    if (StBlst.pbioaddx)
    {
        printf ("\nPort Blaster card installed at\n") ;
        printf ("\tPrinter port     : LPT%d\n",StBlst.pbioaddx) ;
        printf ("\tInterrupt        : %d\n",StBlst.pbintr) ;
    }
}
/* End of File */
