Annotation of Examples/DriverKit/CirrusLogicGD542X/CirrusLogicGD542X_reloc.tproj/CirrusLogicGD542X.m, revision 1.1.1.1

1.1       root        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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.