home *** CD-ROM | disk | FTP | other *** search
/ OpenStep 4.2J (Developer) / os42jdev.iso / NextDeveloper / Examples / DriverKit / CirrusLogicGD542X / CirrusLogicGD542X_reloc.tproj / CirrusLogicGD542X.m < prev    next >
Text File  |  1993-08-06  |  14KB  |  497 lines

  1. /*     Copyright (c) 1992 NeXT Computer, Inc.  All rights reserved. 
  2.  *
  3.  *  CirrusLogicGD542X.m
  4.  *
  5.  */
  6.  
  7.  
  8. #import <driverkit/i386/IOEISADeviceDescription.h>
  9. #import "CirrusLogicGD542X.h"
  10. #import <kernserv/kern_server_types.h>
  11. #import <driverkit/i386/displayRegisters.h>
  12. #import <stdio.h>
  13. #import <string.h>
  14.  
  15. #define    MIN(a,b) (((a)<(b))?(a):(b))
  16.  
  17.  
  18. //
  19. // typedef used to store arrays of register index and values.
  20. // -1 as index indicates end of the set...
  21. //
  22. typedef struct _SVGAIndexValuePair {
  23.     signed short index;
  24.     unsigned char value;
  25. } SVGAIndexValuePair;
  26.  
  27.  
  28. //
  29. // typedef defining a given graphics mode.  A graphics mode
  30. // consists of all the register/value pairs that, when set,
  31. // completely define a mode of operation.
  32. //
  33. typedef struct _CirrusLogicGD542XMode {
  34.     const char *name;            /* human-readable mode name */
  35.     const SVGAIndexValuePair *generalRegisters;
  36.     const SVGAIndexValuePair *sequencerRegisters;
  37.     const SVGAIndexValuePair *crtControllerRegisters;
  38.     const SVGAIndexValuePair *graphicsControllerRegisters;
  39.     const SVGAIndexValuePair *attributeControllerRegisters;
  40. } CirrusLogicGD542XMode;
  41.  
  42.  
  43. /***************************************
  44.  * CirrusLogicGD542X_1024x768x2x60hz mode
  45.  ***************************************/
  46.  
  47. static const SVGAIndexValuePair
  48. CirrusLogicGD542X_1024x768x2x60hz_generalRegisters[] = {
  49.     {0, 0x3F},
  50.     {-1, 0}
  51. };
  52.  
  53. static const SVGAIndexValuePair
  54. CirrusLogicGD542X_1024x768x2x60hz_sequencerRegisters[] = {
  55.     {0, 0x03}, {1, 0x01}, {2, 0x0F}, {3, 0x00}, {4, 0x06},
  56.     {-1, 0}
  57. };
  58.  
  59. static const SVGAIndexValuePair
  60. CirrusLogicGD542X_1024x768x2x60hz_crtControllerRegisters[] = {
  61.     {0x11,0x00},    // Turn off lock allowing changing 0..7
  62.     {0x00,0xA1}, {0x01,0x7F}, {0x02,0x80}, {0x03,0x04}, {0x04,0x88},
  63.     {0x05,0x9E}, {0x06,0x26}, {0x07,0xFD}, {0x08,0x00}, {0x09,0x60},
  64.     {0x0A,0x00}, {0x0B,0x00}, {0x0C,0x00}, {0x0D,0x00}, {0x0E,0x00},
  65.     {0x0F,0x00}, {0x10,0x08}, {0x11,0x8A}, {0x12,0xFF}, {0x13,0x40},
  66.     {0x14,0x00}, {0x15,0x04}, {0x16,0x22}, {0x17,0xC3}, {0x18,0xFF},
  67.     {0x1b,0x02},
  68.     {-1, 0}
  69. };
  70.  
  71. static const SVGAIndexValuePair
  72. CirrusLogicGD542X_1024x768x2x60hz_graphicsControllerRegisters[] = {
  73.     {0x00,0x00}, {0x01,0x00}, {0x02,0x00}, {0x03,0x00}, {0x04,0x00},
  74.     {0x05,0x00}, {0x06,0x05}, {0x07,0x0F}, {0x08,0xFF},
  75.     {-1, 0}
  76. };
  77.  
  78. static const SVGAIndexValuePair
  79. CirrusLogicGD542X_1024x768x2x60hz_attributeControllerRegisters[] = {
  80.     {0x00,0x00}, {0x01,0x01}, {0x02,0x02}, {0x03,0x03}, {0x04,0x04},
  81.     {0x05,0x05}, {0x06,0x14}, {0x07,0x07}, {0x08,0x38}, {0x09,0x39},
  82.     {0x0A,0x3A}, {0x0B,0x3B}, {0x0C,0x3C}, {0x0D,0x3D}, {0x0E,0x3E},
  83.     {0x0F,0x3F}, {0x10,0x01}, {0x11,0x00}, {0x12,0x0F}, {0x13,0x00},
  84.     {0x14,0x00},
  85.     {-1, 0}
  86. };
  87.  
  88.  
  89. static const CirrusLogicGD542XMode
  90. CirrusLogicGD542X_1024x768x2x60hz = {
  91.     "1024x768x2x60hz",
  92.     CirrusLogicGD542X_1024x768x2x60hz_generalRegisters,
  93.     CirrusLogicGD542X_1024x768x2x60hz_sequencerRegisters,
  94.     CirrusLogicGD542X_1024x768x2x60hz_crtControllerRegisters,
  95.     CirrusLogicGD542X_1024x768x2x60hz_graphicsControllerRegisters,
  96.     CirrusLogicGD542X_1024x768x2x60hz_attributeControllerRegisters
  97. };
  98.  
  99.  
  100. /**************************************
  101.  * Framebuffer characteristics.
  102.  **************************************/
  103.  
  104. #define FRAMEBUFFER_ADDRESS ((void *) 0xa0000)
  105.  
  106. static const IODisplayInfo modeTable[] = {
  107.     {
  108.     //
  109.     // CirrusLogicGD542X 1024 x 768 x 2 x 60hz
  110.     //
  111.     1024, 768, 1024, 
  112.     
  113.     //
  114.     // rowbytes =
  115.     //    #bytes/scanline =
  116.     //    ((pixels/line) * (2 bits/pixel) * (byte/8 bits)) =
  117.     //    (pixel width / 4)
  118.     //
  119.     256, 60, 0, IO_2BitsPerPixel, IO_OneIsBlackColorSpace,
  120.     "WW", 0, (void *)&CirrusLogicGD542X_1024x768x2x60hz
  121.     }
  122.     /* Add more modes here. */
  123. };
  124. #define modeTableCount  (sizeof(modeTable) / sizeof(IODisplayInfo))
  125.  
  126.  
  127. @implementation CirrusLogicGD542X
  128.  
  129.  
  130. //
  131. // BEGIN:    Implementation of private routines for SVGA
  132. //
  133.  
  134.  
  135. static void SetBrightness(unsigned int level)
  136. // Description:    Sets the screen's brightness.  This implementation
  137. //        uses a fixed gamma value.  It sets the palette
  138. //        values according to the brightness level.
  139. {
  140.     unsigned char val;
  141.  
  142.     val = EV_SCALE_BRIGHTNESS(level, WHITE_PALETTE_VALUE);
  143.     outb(WRIT_COLR_PEL_AWMR, (unsigned char)WHITE_INDEX);
  144.     outb(WRIT_COLR_PEL_DATA, val);
  145.     outb(WRIT_COLR_PEL_DATA, val);
  146.     outb(WRIT_COLR_PEL_DATA, val);
  147.  
  148.     val = EV_SCALE_BRIGHTNESS(level, LIGHT_GRAY_PALETTE_VALUE);
  149.     outb(WRIT_COLR_PEL_AWMR, (unsigned char)LIGHT_GRAY_INDEX);
  150.     outb(WRIT_COLR_PEL_DATA, val);
  151.     outb(WRIT_COLR_PEL_DATA, val);
  152.     outb(WRIT_COLR_PEL_DATA, val);
  153.  
  154.     val = EV_SCALE_BRIGHTNESS(level, DARK_GRAY_PALETTE_VALUE);
  155.     outb(WRIT_COLR_PEL_AWMR, (unsigned char)DARK_GRAY_INDEX);
  156.     outb(WRIT_COLR_PEL_DATA, val);
  157.     outb(WRIT_COLR_PEL_DATA, val);
  158.     outb(WRIT_COLR_PEL_DATA, val);
  159.  
  160.     val = EV_SCALE_BRIGHTNESS(level, BLACK_PALETTE_VALUE);
  161.     outb(WRIT_COLR_PEL_AWMR, (unsigned char)BLACK_INDEX);
  162.     outb(WRIT_COLR_PEL_DATA, val);
  163.     outb(WRIT_COLR_PEL_DATA, val);
  164.     outb(WRIT_COLR_PEL_DATA, val);
  165. }
  166.  
  167.  
  168. static void setColorMapToLinearMonochrome()
  169. // Description:    Sets the color map to linear monochrome by zeroing
  170. //        out the entire table, then setting the first four
  171. //        palette values correctly.
  172. {
  173.     int i;
  174.  
  175.     for (i = 0; i < 256; i++) {
  176.     outb(WRIT_COLR_PEL_AWMR, i);
  177.     outb(WRIT_COLR_PEL_DATA, 0x00);
  178.     outb(WRIT_COLR_PEL_DATA, 0x00);
  179.     outb(WRIT_COLR_PEL_DATA, 0x00);
  180.     }
  181.     outb(WRIT_COLR_PEL_AWMR, WHITE_INDEX);
  182.     outb(WRIT_COLR_PEL_DATA, WHITE_PALETTE_VALUE);
  183.     outb(WRIT_COLR_PEL_DATA, WHITE_PALETTE_VALUE);
  184.     outb(WRIT_COLR_PEL_DATA, WHITE_PALETTE_VALUE);
  185.     
  186.     outb(WRIT_COLR_PEL_AWMR, LIGHT_GRAY_INDEX);
  187.     outb(WRIT_COLR_PEL_DATA, LIGHT_GRAY_PALETTE_VALUE);
  188.     outb(WRIT_COLR_PEL_DATA, LIGHT_GRAY_PALETTE_VALUE);
  189.     outb(WRIT_COLR_PEL_DATA, LIGHT_GRAY_PALETTE_VALUE);
  190.     
  191.     outb(WRIT_COLR_PEL_AWMR, DARK_GRAY_INDEX);
  192.     outb(WRIT_COLR_PEL_DATA, DARK_GRAY_PALETTE_VALUE);
  193.     outb(WRIT_COLR_PEL_DATA, DARK_GRAY_PALETTE_VALUE);
  194.     outb(WRIT_COLR_PEL_DATA, DARK_GRAY_PALETTE_VALUE);
  195.     
  196.     outb(WRIT_COLR_PEL_AWMR, BLACK_INDEX);
  197.     outb(WRIT_COLR_PEL_DATA, BLACK_PALETTE_VALUE);
  198.     outb(WRIT_COLR_PEL_DATA, BLACK_PALETTE_VALUE);
  199.     outb(WRIT_COLR_PEL_DATA, BLACK_PALETTE_VALUE);
  200. }
  201.  
  202.  
  203. - (void) _selectMode
  204. // Description:    During initialization, this selects the configured mode
  205. //        and sets the display info accordingly.
  206. {
  207.     selectedMode = [self selectMode:modeTable count:modeTableCount valid:NULL];
  208.  
  209.     if (selectedMode < 0) {
  210.     IOLog("%s: Sorry, cannot use requested display mode.\n", [self name]);
  211.     selectedMode = 0;
  212.     }
  213.  
  214.     *[self displayInfo] = modeTable[selectedMode];
  215. }
  216.  
  217.  
  218. - (void)_SVGASetGeneralRegistersForMode:
  219.     (const CirrusLogicGD542XMode *)cirrusLogicGD542XMode
  220. // Description:    Set all the general registers for the given mode.
  221. {
  222.     const SVGAIndexValuePair *regInfo;
  223.  
  224.     regInfo = cirrusLogicGD542XMode->generalRegisters;
  225.     while (regInfo->index != -1) {
  226.     outb(WRIT_EIDR_GEN_MISC_OP, regInfo->value);
  227.     regInfo++;
  228.     }
  229. }
  230.  
  231.  
  232. - (void)_SVGASetSequencerRegistersForMode:
  233.     (const CirrusLogicGD542XMode *)cirrusLogicGD542XMode
  234. // Description:    Set all the sequencer registers for the given mode.
  235. {
  236.     const SVGAIndexValuePair *regInfo;
  237.     
  238.     regInfo = cirrusLogicGD542XMode->sequencerRegisters;
  239.     while (regInfo->index != -1) {
  240.     IOWriteRegister(EIDR_SEQ_ADDR, (char)(regInfo->index), regInfo->value);
  241.     regInfo++;
  242.     }
  243. }
  244.  
  245.  
  246. - (void)_SVGASetCrtControllerRegistersForMode:
  247.     (const CirrusLogicGD542XMode *)cirrusLogicGD542XMode
  248. // Description:    Set all the crt controller registers for the given mode.
  249. {
  250.     const SVGAIndexValuePair *regInfo;
  251.     
  252.     regInfo = cirrusLogicGD542XMode->crtControllerRegisters;
  253.     while (regInfo->index != -1) {
  254.     IOWriteRegister(COLR_CRT_ADDR, (char)(regInfo->index), regInfo->value);
  255.     regInfo++;
  256.     }
  257. }
  258.  
  259.  
  260. - (void)_SVGASetGraphicsControllerRegistersForMode:
  261.     (const CirrusLogicGD542XMode *)cirrusLogicGD542XMode
  262. // Description:    Set all the graphics controller registers for the given mode.
  263. {
  264.     const SVGAIndexValuePair *regInfo;
  265.     
  266.     regInfo = cirrusLogicGD542XMode->graphicsControllerRegisters;
  267.     while (regInfo->index != -1) {
  268.     IOWriteRegister(EIDR_GCR_ADDR, (char)(regInfo->index), regInfo->value);
  269.     regInfo++;
  270.     }
  271. }
  272.  
  273.  
  274. - (void)_SVGASetAttributeControllerRegistersForMode:
  275.     (const CirrusLogicGD542XMode *)cirrusLogicGD542XMode
  276. // Description:    Set all the attribute controller registers for the given mode.
  277. {
  278.     const SVGAIndexValuePair *regInfo;
  279.  
  280.     regInfo = cirrusLogicGD542XMode->attributeControllerRegisters;
  281.     while (regInfo->index != -1) {
  282.     char tmpi;
  283.     inb(READ_COLR_GEN_IN_ST_1);
  284.     tmpi = inb(READ_TOGL_ACR_ADDR);
  285.     tmpi &= ~ACR_MSK;
  286.     tmpi |= (regInfo->index & ACR_MSK);
  287.     outb(WRIT_TOGL_ACR_ADDR, tmpi);
  288.     outb(WRIT_TOGL_ACR_DATA, regInfo->value);
  289.     regInfo++;
  290.     }
  291. }
  292.  
  293.  
  294. //
  295. // END:        Implementation of private routines for SVGA
  296. //
  297.  
  298.  
  299. //
  300. // BEGIN:    EXPORTED methods
  301. //
  302.  
  303.  
  304. - (void)setReadSegment: (unsigned char)segmentNum
  305. // Description:    Select which 64K segment we intend to read from.
  306. {
  307.     outb(0x03ce,0x09);
  308.     outb(0x03cf,(segmentNum << 4));
  309. }
  310.  
  311.  
  312. - (void)setWriteSegment: (unsigned char)segmentNum
  313. // Description:    Select which 64K segment we intend to write to.
  314. {
  315.     outb(0x03ce,0x09);
  316.     outb(0x03cf,(segmentNum << 4));
  317. }
  318.  
  319.  
  320. - (void)setReadPlane: (unsigned char)planeNum
  321. // Description:    Select which of 4 bit planes to read from in planar
  322. //        modes - only one plane can be active at a time.
  323. {
  324.     char tmp;
  325.  
  326.     /* Select plane we are reading from */
  327.     tmp = IOReadRegister(EIDR_GCR_ADDR, GCR_AT_READ_MAPS);
  328.     tmp &= ~GCR_AT_RMS;
  329.     tmp |= (planeNum & GCR_AT_RMS);
  330.     IOWriteRegister(EIDR_GCR_ADDR, GCR_AT_READ_MAPS, tmp);
  331. }
  332.  
  333.  
  334. - (void)setWritePlane: (unsigned char)planeNum
  335. // Description:    Select one of 4 bit planes to write to in planar modes.
  336. //        Although more than one plane can be active at a time,
  337. //        this routine only allows access to 1 plane at a time.
  338. {
  339.     char tmp, plane = 0x01;
  340.  
  341.     //
  342.     // Convert plane num to bit enable.
  343.     //
  344.     plane = plane << (planeNum & 0x03);
  345.  
  346.     //
  347.     // Select plane we are writing to
  348.     //
  349.     tmp = IOReadRegister(EIDR_SEQ_ADDR, SEQ_AT_MPK);
  350.     tmp &= ~(SEQ_AT_EM3 | SEQ_AT_EM2 | SEQ_AT_EM1 | SEQ_AT_EM0);
  351.     tmp |= plane;
  352.     IOWriteRegister(EIDR_SEQ_ADDR, SEQ_AT_MPK, tmp);
  353. }
  354.  
  355.  
  356. - (void)savePlaneAndSegmentSettings
  357. // Description:    Saves the current plane and segment settings.
  358. //        This is not a stack push, so we can only save/
  359. //        restore one group of settings at a time.
  360. {
  361.     writePlaneMask = IOReadRegister(EIDR_SEQ_ADDR, SEQ_AT_MPK);
  362.     readPlaneMask = IOReadRegister(EIDR_GCR_ADDR, GCR_AT_READ_MAPS);
  363.     outb(0x3ce,0x09);
  364.     readSegment = inb(0x3cf);
  365.     writeSegment=readSegment=(readSegment >> 4);
  366. }
  367.  
  368.  
  369. - (void)restorePlaneAndSegmentSettings
  370. // Description:    Restores the current plane and segment settings.
  371. //        This is not a stack pop, so we can only save/
  372. //        restore one group of settings at a time.
  373. {
  374.     IOWriteRegister(EIDR_SEQ_ADDR, SEQ_AT_MPK, writePlaneMask);
  375.     IOWriteRegister(EIDR_GCR_ADDR, GCR_AT_READ_MAPS, readPlaneMask);
  376.     outb(0x3ce, 0x09);
  377.     outb(0x3cf, (readSegment << 4));
  378. }
  379.  
  380.  
  381. - (void)enterSVGAMode
  382. // Description:    Put the display into SVGA mode selectedMode. This
  383. //        typically happens when the window server starts running.
  384. //        We set up all the registers necessary for the given
  385. //        mode and then clear the screen.
  386. {
  387.     IODisplayInfo *displayInfo;
  388.     int totalScreenBytes, bytesLeftToClear, writeSegmentToClear;
  389.  
  390.     [self _SVGASetGeneralRegistersForMode:
  391.         modeTable[selectedMode].parameters];
  392.     [self _SVGASetSequencerRegistersForMode:
  393.         modeTable[selectedMode].parameters];
  394.     [self _SVGASetCrtControllerRegistersForMode:
  395.         modeTable[selectedMode].parameters];
  396.     [self _SVGASetGraphicsControllerRegistersForMode:
  397.         modeTable[selectedMode].parameters];
  398.     [self _SVGASetAttributeControllerRegistersForMode:
  399.         modeTable[selectedMode].parameters];
  400.  
  401.     //
  402.     // re-enable timing sequencer
  403.     //
  404.     IOWriteRegister(EIDR_SEQ_ADDR, SEQ_AT_CRS, 0x00);
  405.     setColorMapToLinearMonochrome();
  406.     
  407.     //
  408.     // Clear the screen.
  409.     //
  410.     displayInfo = [self displayInfo];
  411.     totalScreenBytes = displayInfo->rowBytes * displayInfo->height;
  412.     for (   bytesLeftToClear = totalScreenBytes, writeSegmentToClear = 0;
  413.         bytesLeftToClear > 0;
  414.         bytesLeftToClear -= 0x20000, writeSegmentToClear++) {
  415.     [self setWriteSegment:writeSegmentToClear];
  416.     memset(displayInfo->frameBuffer, 0, MIN(0x20000, bytesLeftToClear));
  417.     }
  418.  
  419.     [self setWriteSegment:0];
  420. }
  421.  
  422.  
  423. - (void)revertToVGAMode
  424. // Description:    Put the display into VGA mode. This typically happens
  425. //        when SoftPC enters full-screen mode.  We set up all the
  426. //        registers necessary for the given mode.
  427. {
  428.     outb(WRIT_EIDR_GEN_MISC_OP, 0xE3);
  429. }
  430.  
  431.  
  432. - initFromDeviceDescription:deviceDescription
  433. // Description:    IODevice method.  Initialize the current instance as
  434. //        per the deviceDescription.  Most importantly, this
  435. //        includes selecting the mode and mapping the frame buffer.
  436. {
  437.     IODisplayInfo *displayInfo;
  438.     const IORange *range;
  439.     const CirrusLogicGD542XMode *cirrusLogicGD542XMode;
  440.  
  441.     if ([super initFromDeviceDescription:deviceDescription] == nil)
  442.     return [super free];
  443.  
  444.     [self _selectMode];
  445.  
  446.     range = [deviceDescription memoryRangeList];
  447.     if (range == 0) {
  448.     IOLog("%s: No memory range set.\n", [self name]);
  449.     return [super free];
  450.     }
  451.     videoRamAddress = range[0].start;
  452.  
  453.     displayInfo = [self displayInfo];
  454.     cirrusLogicGD542XMode = displayInfo->parameters;
  455.  
  456.     displayInfo->frameBuffer =
  457.         (void *)[self mapFrameBufferAtPhysicalAddress:videoRamAddress
  458.          length:0x20000];        //SCOTT--fix this
  459.          
  460.     if (displayInfo->frameBuffer == 0)
  461.     return [super free];
  462.  
  463.     IOLog("%s: Initialized `%s' @ %d Hz.\n", [self name],
  464.     cirrusLogicGD542XMode->name, displayInfo->refreshRate);
  465.  
  466.     return self;
  467. }
  468.  
  469.  
  470. - setBrightness:(int)level token:(int)t
  471. // Description:    This is from the evScreen protocol. We override our superclass
  472. //        on this since it doesn't know how to set our brightness.
  473. {
  474.     if ( level < EV_SCREEN_MIN_BRIGHTNESS
  475.     || level > EV_SCREEN_MAX_BRIGHTNESS )
  476.     {
  477.     IOLog("%s: Invalid arg to setBrightness:%d\n",
  478.         [self name], level );
  479.         
  480.     if (level < EV_SCREEN_MIN_BRIGHTNESS) {
  481.         level = EV_SCREEN_MIN_BRIGHTNESS;
  482.     } else {
  483.         level = EV_SCREEN_MAX_BRIGHTNESS;
  484.     }
  485.     }
  486.     SetBrightness(level);
  487.  
  488.     return self;
  489. }
  490.  
  491.  
  492. //
  493. // END:        EXPORTED methods
  494. //
  495.  
  496. @end
  497.