home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / PROGRAMS / UTILS / HARDWARE / CONFIG16.ZIP / CONFIG.C next >
Encoding:
C/C++ Source or Header  |  1989-08-17  |  16.5 KB  |  673 lines

  1.  
  2. /*********************************/
  3. /*                               */
  4. /*   CONFIG.C - by  Mike Klein   */
  5. /*                               */
  6. /*           ver 1.6             */
  7. /*                               */
  8. /*-------------------------------*/
  9. /*                               */
  10. /* A routine to show computer's  */
  11. /* configuration and optionally  */
  12. /* alter the parent environment  */
  13. /* SETting variables based upon  */
  14. /* the status of/equipment found */
  15. /* in the computer being used.   */
  16. /*                               */
  17. /*********************************/
  18.  
  19.  
  20. /*****************/
  21. /*               */
  22. /* INCLUDE FILES */
  23. /*               */
  24. /*****************/
  25.  
  26. #include <string.h>
  27. #include <dos.h>
  28. #include <stdio.h>
  29. #include <stdlib.h>
  30.  
  31.  
  32. /***********/
  33. /*         */
  34. /* DEFINES */
  35. /*         */
  36. /***********/
  37.  
  38. #define VERSION 1.6
  39. #define TRUE 1
  40. #define FALSE 0
  41.  
  42. #define intvideo(regs) int86(0x10, regs, regs)
  43. #define intmouse(regs) int86(0x33, regs, regs)
  44.  
  45.  
  46. /****************/
  47. /*              */
  48. /* DECLARATIONS */
  49. /*              */
  50. /****************/
  51.  
  52. void put_par_env(char *env_var, char *env_text);
  53. void del_par_env(char *env_var);
  54.  
  55.  
  56. /*************/
  57. /*           */
  58. /* TYPEDEF'S */
  59. /*           */
  60. /*************/
  61.  
  62. typedef unsigned int SEG;
  63. typedef unsigned int LENGTH;
  64.  
  65. char far *par_env;      /* Pointer to parent environment */
  66. LENGTH par_env_len;     /* Length of parent environment  */
  67.  
  68.  
  69. /********/
  70. /*      */
  71. /* MAIN */
  72. /*      */
  73. /********/
  74.  
  75. void main(int argc, char *argv[]) {
  76.  
  77.    char *class;         /* Like model, but only (PC/AT)     */
  78.    char conv[4];        /* Conventional memory size         */
  79.    char *cpu;           /* CPU type (808x, 80286, 80386)    */
  80.    char *exp;           /* Expanded memory? (YES/NO)        */
  81.    char *ext;           /* Extended memory? (YES/NO)        */
  82.    char *fpu;           /* FPU present? (YES/NO)            */
  83.    char *mca;           /* Micro Channel? (YES/NO)          */
  84.    char *mode;          /* Video mode (COLOR/MONOCHROME)    */
  85.    char *model;         /* Model (PC/XT/XT-286/AT/25/30/50  */
  86.                         /*        60/70/80)                 */
  87.    char *mouse;         /* Mouse present? (YES/NO)          */
  88.    char rom_date[9];    /* Computer's ROM date              */
  89.    char *ps2;           /* PS/2 system? (YES/NO)            */
  90.    char version[5];     /* DOS version (2.0, 3.3, etc.)     */
  91.    char *video;         /* Video adapter (MDA, HERC, CGA,   */
  92.                         /*                EGA, PGA, VGA,    */
  93.                         /*                MCGA)             */
  94.  
  95.    unsigned char main;
  96.    unsigned char sub;
  97.  
  98.    unsigned char features;
  99.  
  100.    char far *far_ptr;
  101.    int far *seg_ptr;
  102.    char *string;
  103.    unsigned char byte;
  104.  
  105.    int env_set = FALSE;
  106.  
  107.    register unsigned int i;
  108.  
  109.    union REGS regs;
  110.    struct SREGS sregs;
  111.  
  112.    extern unsigned _psp;
  113.  
  114.    /* Structs for PSP and DOS Memory Control Block (MCB)    */
  115.  
  116.    typedef struct {
  117.       char misc1[22];
  118.       SEG par_seg;
  119.       char misc2[20];
  120.       SEG env_seg;
  121.    } PSP;
  122.  
  123.    /* Compile with byte alignment */
  124.  
  125.    typedef struct {
  126.       char status;         /* Block is in chain or not      */
  127.       SEG owner_psp;       /* PSP segment of block's owner  */
  128.       LENGTH size;         /* Size (in paragraphs) of block */
  129.    } MCB;
  130.  
  131.    MCB far *CONFIGmcb;        /* config.sys MCB    */
  132.    MCB far *COMMANDmcb;       /* command.com MCB   */
  133.    MCB far *ENVmcb;           /* environments MCB  */
  134.    PSP far *COMMANDpsp;       /* command.com PSP   */
  135.  
  136.  
  137.    /***************************/
  138.    /*                         */
  139.    /* COMMAND LINE PARAMETERS */
  140.    /*                         */
  141.    /***************************/
  142.  
  143.    if(argc > 1)
  144.       if(!strcmp(argv[1], "/e") || !strcmp(argv[1], "/E"))
  145.          env_set = TRUE;
  146.       else {
  147.          puts("\nERROR:  Bad parameter...");
  148.          exit(-1);
  149.       }
  150.    else
  151.       env_set = FALSE;
  152.  
  153.  
  154.    /***************************/
  155.    /*                         */
  156.    /* FIND PARENT ENVIRONMENT */
  157.    /*                         */
  158.    /***************************/
  159.  
  160.    regs.x.ax = 0x5200;
  161.    intdosx(®s, ®s, &sregs);
  162.    seg_ptr = MK_FP(sregs.es, regs.x.bx - 2);
  163.  
  164.    CONFIGmcb = MK_FP(*seg_ptr, 0);
  165.  
  166.    COMMANDpsp = MK_FP(FP_SEG(CONFIGmcb) + CONFIGmcb->size + 2, 0);
  167.  
  168.    if(COMMANDpsp->env_seg == 0) {
  169.       /* Environment is in block after parent program */
  170.       COMMANDmcb = MK_FP(FP_SEG(CONFIGmcb) + CONFIGmcb->size + 1, 0);
  171.       par_env = MK_FP(FP_SEG(COMMANDmcb) + COMMANDmcb->size + 2, 0);
  172.    }
  173.    else     /* We have direct ptr to environment */
  174.       par_env = MK_FP(COMMANDpsp->env_seg, 0);
  175.  
  176.    /* MCB of environment is 1 segment lower */
  177.  
  178.    ENVmcb = MK_FP(FP_SEG(par_env) - 1, 0);
  179.  
  180.    par_env_len = ENVmcb->size * 16;          /* Save len of environment    */
  181.  
  182.    printf("\n\nSYSTEM CONFIGURATION v%1.1f\n", VERSION);
  183.    puts("=========================");
  184.  
  185.  
  186.    /*************/
  187.    /*           */
  188.    /* MODEL/MCA */
  189.    /*           */
  190.    /*************/
  191.  
  192.    byte = (unsigned) peekb(0xf000, 0xfffe);  /* Looking in high memory  */
  193.                                              /* for machine ID byte     */
  194.    mca = "NO";
  195.    ps2 = "NO";
  196.  
  197.    switch(byte) {
  198.       case 0xff :
  199.          model = "PC";
  200.          break;
  201.       case 0xfe :
  202.       case 0xfb :
  203.          model = "XT";
  204.          break;
  205.       case 0xfc :
  206.       case 0xfa :
  207.       case 0xf8 :
  208.          regs.x.ax = 0xc000;     /* Get the system environment info  */
  209.          int86x(0x15, ®s, ®s, &sregs);
  210.          main = peekb(sregs.es, regs.x.bx + 0x02);
  211.          if(byte != main) {      /* Some AT's don't support this     */
  212.             model = "AT";        /* function so let's abort          */
  213.             break;
  214.          }
  215.          sub = peekb(sregs.es, regs.x.bx + 0x03);
  216.          features = peekb(sregs.es, regs.x.bx + 0x05);
  217.          if(features & 0x02)
  218.             mca = "YES";
  219.          switch(main) {
  220.             case 0xfc :
  221.                switch(sub) {
  222.                   case 0x02 :
  223.                      model = "XT286";
  224.                      break;
  225.                   case 0x04 :
  226.                      model = "50";
  227.                      ps2 = "YES";
  228.                      break;
  229.                   case 0x05 :
  230.                      model = "60";
  231.                      ps2 = "YES";
  232.                      break;
  233.                   case 0x00 :
  234.                   case 0x01 :
  235.                   default :
  236.                      model = "AT";
  237.                      break;
  238.                }
  239.                break;
  240.             case 0xf8 :
  241.                ps2 = "YES";
  242.                switch(sub) {
  243.                   case 0x00 :
  244.                   case 0x01 :
  245.                      model = "80";
  246.                      break;
  247.                   case 0x04 :
  248.                   case 0x09 :
  249.                   default :
  250.                      model = "70";
  251.                      break;
  252.                }
  253.                break;
  254.             case 0xfa :
  255.                ps2 = "YES";
  256.                switch(sub) {
  257.                   case 0x01 :
  258.                      model = "25";
  259.                      break;
  260.                   case 0x00 :
  261.                   default :
  262.                      model = "30";
  263.                      break;
  264.                }
  265.                break;
  266.             default :
  267.                model = "N/A";
  268.                break;
  269.          }
  270.          break;
  271.       default :
  272.          model = "N/A";
  273.          break;
  274.    }
  275.    printf("MODEL.....%s\n", model);
  276.    printf("PS/2......%s\n", ps2);
  277.    printf("MCA.......%s\n", mca);
  278.    if(env_set) {
  279.       put_par_env("MODEL", model);
  280.       put_par_env("PS/2", ps2);
  281.       put_par_env("MCA", mca);
  282.    }
  283.  
  284.  
  285.    /************/
  286.    /*          */
  287.    /* CPU TYPE */
  288.    /*          */
  289.    /************/
  290.  
  291.    asm   pushf
  292.    asm   xor   ax,ax
  293.    asm   push  ax
  294.    asm   popf
  295.    asm   pushf
  296.    asm   pop   ax
  297.    asm   and   ax,0f000h
  298.    asm   cmp   ax,0f000h
  299.    asm   jz    is_808x
  300.  
  301.    asm   mov   ax,07000h   /* If we can't set bits 12-14 then  */
  302.    asm   push  ax          /* CPU is 80286                     */
  303.    asm   popf
  304.    asm   pushf
  305.    asm   pop   ax
  306.    asm   and   ax,07000h
  307.    asm   jz    is_80286
  308.  
  309.    is_80386 :
  310.    asm   mov   ax,386h
  311.    asm   jmp   done
  312.  
  313.    is_80286 :
  314.    asm   mov   ax,286h
  315.    asm   jmp   done
  316.  
  317.    is_808x :
  318.    asm   mov   ax,86h
  319.  
  320.    done:
  321.    asm   popf
  322.  
  323.    switch(_AX) {
  324.       case 0x386 :
  325.          cpu = "80386";
  326.          class = "AT";
  327.          break;
  328.       case 0x286 :
  329.          cpu = "80286";
  330.          class = "AT";
  331.          break;
  332.       case 0x86 :
  333.          cpu = "808x";
  334.          class = "PC";
  335.          break;
  336.       default :
  337.          cpu = "N/A";
  338.          break;
  339.    }
  340.    printf("CPU.......%s\n", cpu);
  341.    printf("CLASS.....%s\n", class);
  342.    if(env_set) {
  343.       put_par_env("CPU", cpu);
  344.       put_par_env("CLASS", class);
  345.    }
  346.  
  347.  
  348.    /**************/
  349.    /*            */
  350.    /* MATH CHIP? */
  351.    /*            */
  352.    /**************/
  353.  
  354.    int86(0x11, ®s, ®s);          /* Get BIOS equip word for FPU   */
  355.    fpu = (regs.x.ax & 0x02) ? "YES" : "NO";
  356.  
  357.    printf("FPU.......%s\n", fpu);
  358.    if(env_set)
  359.       put_par_env("FPU", fpu);
  360.  
  361.  
  362.    /***********************/
  363.    /*                     */
  364.    /* CONVENTIONAL MEMORY */
  365.    /*                     */
  366.    /***********************/
  367.  
  368.    int86(0x12, ®s, ®s);          /* INT 0x12 returns conv memory      */
  369.    if((regs.x.ax % 2) != 0)            /* Some systems report 1 Kbyte less  */
  370.       ++regs.x.ax;                     /* than actual, so we compensate     */
  371.    sprintf(conv, "%u", regs.x.ax);
  372.  
  373.    printf("CONV......%s\n", conv);
  374.    if(env_set)
  375.       put_par_env("CONV", conv);
  376.  
  377.  
  378.    /*******************/
  379.    /*                 */
  380.    /* EXPANDED MEMORY */
  381.    /*                 */
  382.    /*******************/
  383.  
  384.    string = "EMMXXXX0";
  385.  
  386.    regs.x.ax = 0x3567;
  387.    intdosx(®s, ®s, &sregs);
  388.    far_ptr = MK_FP(sregs.es, 10);
  389.  
  390.    for(i=0; i < 8; i++) {
  391.       if(far_ptr[i] != string[i]) {
  392.          exp = "NO";
  393.          break;
  394.       }
  395.    }
  396.    if(i == 8) {
  397.       exp = "YES";
  398.       regs.h.ah = 0x42;
  399.       int86(0x67, ®s, ®s);
  400.    }
  401.  
  402.    printf("EXP.......%s", exp);
  403.    if(i == 8)
  404.       printf(" (%dK)\n", regs.x.dx * 16 - 640);
  405.    else
  406.       printf("\n");
  407.    if(env_set)
  408.       put_par_env("EXP", exp);
  409.  
  410.  
  411.    /*******************/
  412.    /*                 */
  413.    /* EXTENDED MEMORY */
  414.    /*                 */
  415.    /*******************/
  416.  
  417.    /* This code must follow the CPU code  */
  418.  
  419.    if(! strcmp(class, "AT")) {
  420.       regs.x.ax = 0x8800;
  421.       int86(0x15, ®s, ®s);
  422.       i = regs.x.ax;
  423.       if((i != 0x8800) && (i != 0x0000))
  424.          ext = "YES";
  425.       else
  426.          ext = "NO";
  427.    }
  428.    else
  429.       ext = "NO";
  430.  
  431.    printf("EXT.......%s", ext);
  432.    if(!strcmp(ext, "YES"))
  433.       printf(" (%dK)\n", i);
  434.    else
  435.       printf("\n");
  436.    if(env_set)
  437.       put_par_env("EXT", ext);
  438.  
  439.  
  440.    /**********/
  441.    /*        */
  442.    /* MOUSE? */
  443.    /*        */
  444.    /**********/
  445.  
  446.    regs.x.ax = 0x00;                   /* Mouse Func 0 - initialize  */
  447.    intmouse(®s);
  448.    if(regs.x.ax)
  449.       mouse = "YES";
  450.    else
  451.       mouse = "NO";
  452.  
  453.    printf("MOUSE.....%s\n", mouse);
  454.    if(env_set)
  455.       put_par_env("MOUSE", mouse);
  456.  
  457.  
  458.    /************/
  459.    /*          */
  460.    /* ROM DATE */
  461.    /*          */
  462.    /************/
  463.  
  464.    far_ptr = MK_FP(0xf000, 0xfff5);    /* Make pointer to address    */
  465.                                        /* of computer's ROM date     */
  466.    if(far_ptr[2] == far_ptr[5]) {
  467.       for(i=0; i<8; ++i)
  468.          rom_date[i] = far_ptr[i];     /* Make string from far_ptr   */
  469.       rom_date[i] = '\0';
  470.    }
  471.    else
  472.       strcpy(rom_date, "N/A");
  473.  
  474.    printf("ROM DATE..%s\n", rom_date);
  475.    if(env_set)
  476.       put_par_env("ROM_DATE", rom_date);
  477.  
  478.  
  479.    /**************/
  480.    /*            */
  481.    /* VIDEO MODE */
  482.    /*            */
  483.    /**************/
  484.  
  485.    regs.x.ax = 0x0f00;
  486.    intvideo(®s);
  487.    switch(regs.h.al) {
  488.       case 0x00 :
  489.       case 0x02 :
  490.       case 0x07 :
  491.          mode = "MONOCHROME";
  492.          break;
  493.       default :
  494.          mode = "COLOR";
  495.          break;
  496.    }
  497.  
  498.    printf("MODE......%s\n", mode);
  499.    if(env_set)
  500.       put_par_env("MODE", mode);
  501.  
  502.  
  503.    /*****************/
  504.    /*               */
  505.    /* VIDEO ADAPTER */
  506.    /*               */
  507.    /*****************/
  508.  
  509.    regs.x.ax = 0x1a00;              /* If function supported (_AL=0x1A) */
  510.    intvideo(®s);
  511.    if(regs.h.al == 0x1a) {
  512.       switch(regs.h.bl) {
  513.          case 0x01 :
  514.             video = "MDA";
  515.             break;
  516.          case 0x02 :
  517.             video = "CGA";
  518.             break;
  519.          case 0x04 :
  520.          case 0x05 :
  521.             video = "EGA";
  522.             break;
  523.          case 0x06 :
  524.             video = "PGA";
  525.             break;
  526.          case 0x07 :
  527.          case 0x08 :
  528.             video = "VGA";
  529.             break;
  530.          case 0x0a :
  531.          case 0x0b :
  532.          case 0x0c :
  533.             video = "MCGA";
  534.             break;
  535.          default :
  536.             video = "VGA";
  537.             break;
  538.       }
  539.    }
  540.    else {
  541.       regs.h.ah = 0x12;                /* Get config info for EGA/VGA      */
  542.       regs.h.bl = 0x10;
  543.       intvideo(®s);
  544.       if(regs.h.bl != 0x10)
  545.          video = "EGA";                /* BL changed? Then EGA             */
  546.       else {
  547.          regs.h.ah = 0x0f;             /* See if color or mono             */
  548.          intvideo(®s);
  549.          if(regs.h.al == 7) {
  550.             byte = inportb(0x3ba) & 0x80;    /* Read CRT status port, mask bit 7
  551. */
  552.             for(i=0; i<32767; i++)           /* Will bit 7 change?
  553.               */
  554.                if(byte != (inportb(0x3ba) & 0x80))
  555.                   break;                     /* If bit 7 didn't change, then MDA
  556. */
  557.             video = (i != 32767) ? "HERC" : "MDA";
  558.          }
  559.          else
  560.             video = "CGA";
  561.       }
  562.    }
  563.    printf("VIDEO.....%s\n", video);
  564.    if(env_set)
  565.       put_par_env("VIDEO", video);
  566.  
  567.  
  568.    /***************/
  569.    /*             */
  570.    /* DOS VERSION */
  571.    /*             */
  572.    /***************/
  573.  
  574.    regs.h.ah = 0x30;                   /* INT 0x21 FUNC 0x30 to get DOS */
  575.    intdos(®s, ®s);               /* version number                */
  576.  
  577.    sprintf(version, "%u.%u", (unsigned) regs.h.al, (unsigned) regs.h.ah);
  578.    printf("VERSION...%s\n", version);
  579.    if(env_set)
  580.       put_par_env("VERSION", version);
  581.  
  582.    puts("=========================\n");
  583.  
  584. }
  585.  
  586.  
  587. /***************/
  588. /*             */
  589. /* PUT_PAR_ENV */
  590. /*             */
  591. /***************/
  592.  
  593. void put_par_env(char *env_var, char *env_text) {
  594.  
  595.    char far *far0;
  596.    LENGTH len;
  597.    char env_str[256];
  598.    char *str;
  599.  
  600.    strcpy(env_str, env_var);           /* Create environment string     */
  601.    strcat(env_str, "=");
  602.    strcat(env_str, env_text);
  603.    strupr(env_str);
  604.  
  605.    del_par_env(env_var);               /* Delete variable of same name  */
  606.  
  607.    /* Find end of environment by looking for 2 NULLS */
  608.    for(far0 = par_env, len = 0; !(!*far0 && !*(far0+1)); ++far0, ++len)
  609.       ;
  610.  
  611.    len = par_env_len - (len + 2);      /* Get free space in environment */
  612.  
  613.    if(len < strlen(env_str) + 1) {     /* If out of room, return error  */
  614.       puts("\nERROR:  Out of environment space...\n");
  615.       exit(-1);
  616.    }
  617.  
  618.    str = env_str;
  619.  
  620.    for(++far0; *str; *far0++ = *str++) /* Copy str to end of par env    */
  621.       ;
  622.  
  623.    *far0 = 0;  /* End env with 2 nulls */
  624.    ++far0;
  625.    *far0 = 0;
  626.  
  627. }
  628.  
  629.  
  630. /***************/
  631. /*             */
  632. /* DEL_PAR_ENV */
  633. /*             */
  634. /***************/
  635.  
  636. void del_par_env(char *env_var) {
  637.  
  638.    char far *far1;      /* Beginning of next variable */
  639.    char far *far2;      /* Beginning of the variable  */
  640.    char *str;           /* env_var ptr used in search */
  641.  
  642.    int found = FALSE;   /* End of search flag         */
  643.  
  644.    far1 = par_env;
  645.  
  646.    while(*far1 && !found) {   /* Find start of variable to delete */
  647.       str = env_var;
  648.       far2 = far1;
  649.       for(;(*far1 == *str) && (*far1 != '=') && *far1 && *str; ++far1, ++str)
  650.          ;
  651.       if((!*str) && (*far1 == '='))
  652.          found = TRUE;        /* We found it! */
  653.       for(; *far1; ++far1)
  654.          ;
  655.       ++far1;
  656.    }
  657.  
  658.    if(!*far1 && !found)       /* Find env_var?        */
  659.       return;                 /* No, we didn't        */
  660.  
  661.    /* Shift environment down, to cover env_var        */
  662.  
  663.    for(; !(!*far1 && !*(far1+1)); *far2++ = *far1++)
  664.       ;
  665.  
  666.    *far2 = 0;  /* End env with 2 nulls */
  667.    ++far2;
  668.    *far2 = 0;
  669.  
  670. }
  671.  
  672. /