home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 8 Other / 08-Other.zip / set6x86.zip / set6x86.c < prev    next >
C/C++ Source or Header  |  1998-01-03  |  8KB  |  241 lines

  1. /*  get/set6x86: a tool for changing Cyrix 6x86 configuration registers
  2.  *
  3.  *  Copyright (C) 1996  Koen Gadeyne
  4.  *  Modifications for OS/2 port by Greg Kondrasuk, 1997.
  5.  *
  6.  *  This program is free software; you can redistribute it and/or modify
  7.  *  it under the terms of the GNU General Public License as published by
  8.  *  the Free Software Foundation; either version 2 of the License, or
  9.  *  (at your option) any later version.
  10.  *
  11.  *  This program is distributed in the hope that it will be useful,
  12.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  *  GNU General Public License for more details.
  15.  *
  16.  *  You should have received a copy of the GNU General Public License
  17.  *  along with this program; if not, write to the Free Software
  18.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  */
  20.  
  21.  
  22. /***
  23.  *** This is just a hacking tool! Use at your own risk. It was NOT intended to be
  24.  *** idiot proof! If you don't understand all this, then don't bother trying to use it.
  25.  ***
  26.  ***/
  27.  
  28. #include <stdio.h>
  29. #include <string.h>
  30. #include <unistd.h>
  31. #include <stdarg.h>
  32. #include <stdlib.h>
  33. #include <string.h>
  34. #include <sys/hw.h>
  35.  
  36. #define outb(data,port) _outp32(port,data)
  37. #define inb(port) _inp32(port)
  38. #define ioperm(x,y,z) (0)
  39. #define VERSION 1.5
  40.  
  41. #ifndef TRUE
  42. #  define TRUE (1)
  43. #endif
  44. #ifndef FALSE
  45. #  define FALSE (0)
  46. #endif
  47.  
  48. typedef int bool;
  49.  
  50. char *CommandName;
  51.  
  52.  
  53. //////////////////////////////////////////////////////////////////////////
  54. // Function: get_IO_range
  55. //////////////////////////////////////////////////////////////////////////
  56. void get_IO_range(int start, int len)
  57. {
  58.    if (ioperm(start, len, 1) != 0) {
  59.       perror("I/O Permissions");
  60.       fprintf(stderr,"Cannot get I/O permissions for hardware address range 0x%x-0x%x.\n\
  61.              You must be superuser, or the program must be setuid root!\n", start, start+len-1);
  62.  
  63.       exit(1);
  64.    }
  65. }
  66.  
  67. //////////////////////////////////////////////////////////////////////////
  68. // Function: check_int_range
  69. //////////////////////////////////////////////////////////////////////////
  70. void check_int_range(int cvalue, int lmin, int lmax, char* descstr)
  71. {
  72.    if (cvalue<lmin || cvalue>lmax) {
  73.       fprintf(stderr,"%s = %d (0x%x) out of range [%d..%d]!\n", descstr, cvalue, cvalue, lmin, lmax);
  74.  
  75.       exit(1);
  76.    }
  77. }
  78.  
  79. //////////////////////////////////////////////////////////////////////////
  80. // Function: getint
  81. // Description: Converts the int in 'instring' into an integer. Must be
  82. //              within specified limits 'lmin' and 'lmax'. 'descrstring'
  83. //              contains a description of the number to be parsed, used
  84. //              in the error message.
  85. //////////////////////////////////////////////////////////////////////////
  86. int getint(char* instring, char* descrstring, int lmin, int lmax)
  87. {
  88.    char** errstr=NULL;
  89.    int readint;
  90.    readint = strtol(instring,errstr,0);
  91.  
  92.    if (errstr) {
  93.       fprintf(stderr,"Illegal character '%s' in %s: '%s'\n", *errstr, descrstring, instring);
  94.       exit(1);
  95.    }
  96.  
  97.    check_int_range(readint, lmin, lmax, descrstring);
  98.  
  99.    return(readint);
  100. }
  101.  
  102. //////////////////////////////////////////////////////////////////////////
  103. // Function: int_to_bin
  104. //////////////////////////////////////////////////////////////////////////
  105. char* int_to_bin(int num, int bits)
  106. {
  107.    static char binstr[sizeof(long int)+1];
  108.    int i;
  109.  
  110.    for (i=0; i<bits; i++)
  111.       binstr[i] = 0x30; // char '0'
  112.  
  113.    binstr[bits] = 0x00;
  114.  
  115.    for (i=0; i<bits; i++)
  116.       binstr[bits-1-i] += ((num >> i) & 0x00000001);
  117.  
  118.    return(binstr);
  119. }
  120.  
  121. //////////////////////////////////////////////////////////////////////////
  122. // Function: usage
  123. // Description: displays program usage information.
  124. //////////////////////////////////////////////////////////////////////////
  125. void usage(bool setreg)
  126. {
  127.    printf("Inside the usage function.\n");
  128.    printf("%s %.1f (c) 1996 Koen Gadeyne.\n", CommandName, VERSION);
  129.    printf("Modified for OS/2 by Greg Kondrasuk.");
  130.    printf("\n"
  131.    "  Usage: %s [-hp] [-r register_index] %s\n\n", CommandName, (setreg) ? "[-d data] | [-sc bitmask]" : "");
  132.    printf("  Options: -h  print usage information\n"
  133.    "%s"\
  134.    "\n"
  135.    "  register_index: An index to the specified Cyrix 6x86 config register,\n"
  136.    "                  In decimal (e.g. '24'), hex ('0x18') or octal ('030').\n"
  137.    "\n"
  138.    "%s\n",
  139.    (setreg) ? \
  140.    "           -p  silent mode: don't spread the news (no output)\n"\
  141.    "           -r  `register_index' specifies the register to use\n"\
  142.    "           -d  `data' is a raw value to program into the register\n"\
  143.    "           -s  `data' is a bitmask for setting bits in the register\n"\
  144.    "           -c  `data' is a bitmask for clearing bits in the register\n"\
  145.    : \
  146.    "           -p  pipeable output: only hex register contents are printed\n",\
  147.    (setreg) ? \
  148.    "  data: for the -d option, the raw data to program into the specified\n"\
  149.    "        register (dec|hex|oct), or the bitmask for the -s and -c options.\n"\
  150.    : \
  151.    "");
  152. }
  153.  
  154.  
  155. /***********************************************************************************************************/
  156.  
  157. int main (int argc, char* argv[])
  158. {
  159.    int c;
  160.    int tmpbyte=0;
  161.    int regnum=0;
  162.    bool setreg = FALSE;
  163.    bool silent = FALSE;
  164.    bool arg_is_setmask=FALSE;
  165.    bool arg_is_clearmask=FALSE;
  166.    char* commandfilename;
  167.    int data=0;
  168.  
  169.  
  170.    // See what action is required: read or write
  171.  
  172.    CommandName = argv[0];
  173.    commandfilename = strrchr(CommandName, '\\');
  174.  
  175.    if (commandfilename)
  176.       commandfilename++;
  177.    else
  178.       commandfilename = CommandName;
  179.  
  180.    setreg = (!strnicmp(commandfilename,"set",3));
  181.  
  182.  
  183.  
  184.    // command-line argument parsing
  185.  
  186.    while ((c = getopt (argc, argv, "hpr:d:s:c:")) != EOF) {
  187.       switch (c) {
  188.  
  189.          case 'h': usage(setreg);
  190.                    exit(0);
  191.                    break;
  192.          case 'p': silent = TRUE;
  193.                    break;
  194.          case 'r': regnum = getint( optarg, "register index", 0, 255 );
  195.                    break;
  196.          case 'd': data = getint( optarg, "register data", 0, 255 );
  197.                    break;
  198.          case 's': arg_is_setmask = TRUE;
  199.                    data = getint( optarg, "register data", 0, 255 );
  200.                    break;
  201.          case 'c': arg_is_clearmask = TRUE;
  202.                    data = getint( optarg, "register data", 0, 255 );
  203.                    break;
  204.          case '?': usage(setreg);
  205.                    exit(1);
  206.                    break;
  207.          default:  fprintf(stderr,"getopt returned unknown token '%c'.\n",c);
  208.                    exit(1);
  209.       }
  210.    }
  211.  
  212.    get_IO_range(0x22, 2);
  213.  
  214.    if (setreg) {
  215.       if (arg_is_clearmask || arg_is_setmask) {
  216.  
  217.          outb(regnum, 0x22); tmpbyte = inb(0x23);  // read original data
  218.  
  219.          if (arg_is_clearmask)
  220.             data = tmpbyte & ~data;
  221.          if (arg_is_setmask)
  222.             data = tmpbyte | data;
  223.       }
  224.  
  225.       outb(regnum, 0x22); outb(data, 0x23);          // write data
  226.    }
  227.  
  228.    outb(regnum, 0x22); tmpbyte = inb(0x23);         // read back data
  229.  
  230.    if (!silent)
  231.        printf("Cyrix 6x86 config register, index %d (=0x%x) contains %d (=0x%02x =b%s)\n",
  232.                regnum, regnum, tmpbyte, tmpbyte, int_to_bin(tmpbyte,8));
  233.  
  234.    else if (!setreg)                // "getreg" needs to output _something_
  235.            printf("0x%x\n", tmpbyte);
  236.  
  237.  
  238.    return(0);
  239.  
  240. }  // end main
  241.