home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / utils / console / svgatext.3 / svgatext / SVGATextMode-1.3 / XFREE / common_hw / STG1703clk.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-10-29  |  3.2 KB  |  140 lines

  1. /* $XFree86: xc/programs/Xserver/hw/xfree86/common_hw/STG1703clk.c,v 3.3 1995/07/12 15:37:25 dawes Exp $ */
  2. /*
  3.  * Copyright 1995 The XFree86 Project, Inc
  4.  *
  5.  * programming for the STG1703 clock derived from the code in the Mach64
  6.  * server (by Kevin Martin).
  7.  */
  8.  
  9. #include "compiler.h"
  10. #define NO_OSLIB_PROTOTYPES
  11. #include "xf86_OSlib.h"
  12.  
  13. extern int vgaIOBase;
  14.  
  15.  
  16. /* when RS2 = 0 */
  17.  
  18. #define PALETTE_RAM_WRITE_ADDRESS            0x03C8
  19. #define PALETTE_RAM_DATA_REGISTER            0x03C9
  20. #define PIXEL_READ_MASK_REGISTER             0x03C6
  21. #define PALETTE_RAM_READ_ADDRESS             0x03C7
  22.  
  23. /* when RS2 = 1 */
  24. #define INDEX_LO              0x03C8
  25. #define INDEXED_REG           0x03C9
  26. #define PIXEL_COMMAND         0x03C6
  27. #define INDEX_HI              0x03C7
  28.  
  29. #define MIN_N1        6
  30.  
  31. #define FREQ_MIN              8500
  32. #define FREQ_MAX            135000
  33. #define STG1703_REF_FREQ     14318
  34.  
  35.  
  36. #if NeedFunctionPrototypes
  37. static void 
  38. s3ProgramSTG1703Clock(unsigned int program_word, int clk)
  39. #else
  40. static void s3ProgramSTG1703Clock(program_word, clk)
  41. unsigned int program_word;
  42. int clk;
  43. #endif
  44. {
  45.    unsigned char tmp, oldCR55;
  46.    int vgaCRAddr, vgaCRData;
  47.  
  48.    vgaCRAddr = vgaIOBase + 4;
  49.    vgaCRData = vgaIOBase + 5;
  50.  
  51.    /* RS2 controlled in CR55 bit 0 */
  52.    outb(vgaCRAddr, 0x55);
  53.    oldCR55 = inb(vgaCRData);
  54.    /* set bit 0 of CR55 to 1 to set RS2 to 1 to make sure we are
  55.       talking to correct registers */
  56.    outb(vgaCRData, (oldCR55 & 0xFC) | 0x01);
  57.  
  58.    outb(INDEX_LO, (clk << 1) + 0x20);
  59.    outb(INDEX_HI, 0);
  60.    outb(INDEXED_REG, (program_word & 0xff00) >> 8);
  61.    outb(INDEXED_REG, program_word & 0xff);
  62.    
  63.    usleep(10000);
  64.  
  65.    /* that's done, now select clock through register 0x42 on S3 */
  66.  
  67.    tmp = inb(0x3CC);
  68.    outb(0x3C2, tmp | 0x0C);
  69.    outb(vgaCRAddr, 0x042);
  70.    outb(vgaCRData, clk);
  71.  
  72.    /* put the value of 0x55 back */
  73.    /* if we don't do this, and the server doesn't set CR55 and assumes it
  74.       is okay, when it tries to write to the DAC it will the clock registers
  75.    */
  76.  
  77.    outb(vgaCRAddr, 0x55);
  78.    outb(vgaCRData, oldCR55);
  79. }
  80.  
  81.  
  82. #if NeedFunctionPrototypes
  83. void STG1703SetClock(long freq, int clk)
  84. #else
  85. void
  86. STG1703SetClock(freq, clk)
  87. long freq;
  88. int clk;
  89. #endif
  90. {
  91.    unsigned int program_word;
  92.    unsigned int temp, tempB;
  93.    unsigned short tempA, remainder, preRemainder, divider;
  94.  
  95.    if (freq < FREQ_MIN)
  96.       freq = FREQ_MIN;
  97.    else if (freq > FREQ_MAX)
  98.       freq = FREQ_MAX;
  99.  
  100.    divider = 0;
  101.    while (freq < (FREQ_MIN << 3)) {
  102.       freq <<= 1;
  103.       divider += 0x20;
  104.    }
  105.  
  106.    temp = (unsigned int)(freq);
  107.    temp = (unsigned int)(temp * (MIN_N1 + 2));
  108.    temp -= (short)(STG1703_REF_FREQ << 1);
  109.  
  110.    tempA = MIN_N1;
  111.    preRemainder = 0xffff;
  112.  
  113.    do {
  114.       tempB = temp;
  115.       remainder = tempB % STG1703_REF_FREQ;
  116.       tempB = tempB / STG1703_REF_FREQ;
  117.  
  118.       if ((tempB & 0xffff) <= 127 && (remainder <= preRemainder)) {
  119.      preRemainder = remainder;
  120.      divider &= ~0x1f;
  121.      divider |= tempA;
  122.      divider = (divider & 0x00ff) + ((tempB & 0xff) << 8);
  123.       }
  124.  
  125.       temp += freq;
  126.       tempA++;
  127.    } while (tempA <= (MIN_N1 << 1));
  128.  
  129.    program_word = divider;
  130.  
  131.    /*
  132.     * M  = (program_word & 0x7F) >> 8
  133.     * N1 = program_word & 0x1F
  134.     * N2 = (program_word & 0x60) >> 5
  135.     */
  136.  
  137.    s3ProgramSTG1703Clock(program_word, clk);
  138.    return;
  139. }
  140.