home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (c) 1992 NeXT Computer, Inc. All rights reserved.
- *
- * CirrusLogicGD542X.m
- *
- */
-
-
- #import <driverkit/i386/IOEISADeviceDescription.h>
- #import "CirrusLogicGD542X.h"
- #import <kernserv/kern_server_types.h>
- #import <driverkit/i386/displayRegisters.h>
- #import <stdio.h>
- #import <string.h>
-
- #define MIN(a,b) (((a)<(b))?(a):(b))
-
-
- //
- // typedef used to store arrays of register index and values.
- // -1 as index indicates end of the set...
- //
- typedef struct _SVGAIndexValuePair {
- signed short index;
- unsigned char value;
- } SVGAIndexValuePair;
-
-
- //
- // typedef defining a given graphics mode. A graphics mode
- // consists of all the register/value pairs that, when set,
- // completely define a mode of operation.
- //
- typedef struct _CirrusLogicGD542XMode {
- const char *name; /* human-readable mode name */
- const SVGAIndexValuePair *generalRegisters;
- const SVGAIndexValuePair *sequencerRegisters;
- const SVGAIndexValuePair *crtControllerRegisters;
- const SVGAIndexValuePair *graphicsControllerRegisters;
- const SVGAIndexValuePair *attributeControllerRegisters;
- } CirrusLogicGD542XMode;
-
-
- /***************************************
- * CirrusLogicGD542X_1024x768x2x60hz mode
- ***************************************/
-
- static const SVGAIndexValuePair
- CirrusLogicGD542X_1024x768x2x60hz_generalRegisters[] = {
- {0, 0x3F},
- {-1, 0}
- };
-
- static const SVGAIndexValuePair
- CirrusLogicGD542X_1024x768x2x60hz_sequencerRegisters[] = {
- {0, 0x03}, {1, 0x01}, {2, 0x0F}, {3, 0x00}, {4, 0x06},
- {-1, 0}
- };
-
- static const SVGAIndexValuePair
- CirrusLogicGD542X_1024x768x2x60hz_crtControllerRegisters[] = {
- {0x11,0x00}, // Turn off lock allowing changing 0..7
- {0x00,0xA1}, {0x01,0x7F}, {0x02,0x80}, {0x03,0x04}, {0x04,0x88},
- {0x05,0x9E}, {0x06,0x26}, {0x07,0xFD}, {0x08,0x00}, {0x09,0x60},
- {0x0A,0x00}, {0x0B,0x00}, {0x0C,0x00}, {0x0D,0x00}, {0x0E,0x00},
- {0x0F,0x00}, {0x10,0x08}, {0x11,0x8A}, {0x12,0xFF}, {0x13,0x40},
- {0x14,0x00}, {0x15,0x04}, {0x16,0x22}, {0x17,0xC3}, {0x18,0xFF},
- {0x1b,0x02},
- {-1, 0}
- };
-
- static const SVGAIndexValuePair
- CirrusLogicGD542X_1024x768x2x60hz_graphicsControllerRegisters[] = {
- {0x00,0x00}, {0x01,0x00}, {0x02,0x00}, {0x03,0x00}, {0x04,0x00},
- {0x05,0x00}, {0x06,0x05}, {0x07,0x0F}, {0x08,0xFF},
- {-1, 0}
- };
-
- static const SVGAIndexValuePair
- CirrusLogicGD542X_1024x768x2x60hz_attributeControllerRegisters[] = {
- {0x00,0x00}, {0x01,0x01}, {0x02,0x02}, {0x03,0x03}, {0x04,0x04},
- {0x05,0x05}, {0x06,0x14}, {0x07,0x07}, {0x08,0x38}, {0x09,0x39},
- {0x0A,0x3A}, {0x0B,0x3B}, {0x0C,0x3C}, {0x0D,0x3D}, {0x0E,0x3E},
- {0x0F,0x3F}, {0x10,0x01}, {0x11,0x00}, {0x12,0x0F}, {0x13,0x00},
- {0x14,0x00},
- {-1, 0}
- };
-
-
- static const CirrusLogicGD542XMode
- CirrusLogicGD542X_1024x768x2x60hz = {
- "1024x768x2x60hz",
- CirrusLogicGD542X_1024x768x2x60hz_generalRegisters,
- CirrusLogicGD542X_1024x768x2x60hz_sequencerRegisters,
- CirrusLogicGD542X_1024x768x2x60hz_crtControllerRegisters,
- CirrusLogicGD542X_1024x768x2x60hz_graphicsControllerRegisters,
- CirrusLogicGD542X_1024x768x2x60hz_attributeControllerRegisters
- };
-
-
- /**************************************
- * Framebuffer characteristics.
- **************************************/
-
- #define FRAMEBUFFER_ADDRESS ((void *) 0xa0000)
-
- static const IODisplayInfo modeTable[] = {
- {
- //
- // CirrusLogicGD542X 1024 x 768 x 2 x 60hz
- //
- 1024, 768, 1024,
-
- //
- // rowbytes =
- // #bytes/scanline =
- // ((pixels/line) * (2 bits/pixel) * (byte/8 bits)) =
- // (pixel width / 4)
- //
- 256, 60, 0, IO_2BitsPerPixel, IO_OneIsBlackColorSpace,
- "WW", 0, (void *)&CirrusLogicGD542X_1024x768x2x60hz
- }
- /* Add more modes here. */
- };
- #define modeTableCount (sizeof(modeTable) / sizeof(IODisplayInfo))
-
-
- @implementation CirrusLogicGD542X
-
-
- //
- // BEGIN: Implementation of private routines for SVGA
- //
-
-
- static void SetBrightness(unsigned int level)
- // Description: Sets the screen's brightness. This implementation
- // uses a fixed gamma value. It sets the palette
- // values according to the brightness level.
- {
- unsigned char val;
-
- val = EV_SCALE_BRIGHTNESS(level, WHITE_PALETTE_VALUE);
- outb(WRIT_COLR_PEL_AWMR, (unsigned char)WHITE_INDEX);
- outb(WRIT_COLR_PEL_DATA, val);
- outb(WRIT_COLR_PEL_DATA, val);
- outb(WRIT_COLR_PEL_DATA, val);
-
- val = EV_SCALE_BRIGHTNESS(level, LIGHT_GRAY_PALETTE_VALUE);
- outb(WRIT_COLR_PEL_AWMR, (unsigned char)LIGHT_GRAY_INDEX);
- outb(WRIT_COLR_PEL_DATA, val);
- outb(WRIT_COLR_PEL_DATA, val);
- outb(WRIT_COLR_PEL_DATA, val);
-
- val = EV_SCALE_BRIGHTNESS(level, DARK_GRAY_PALETTE_VALUE);
- outb(WRIT_COLR_PEL_AWMR, (unsigned char)DARK_GRAY_INDEX);
- outb(WRIT_COLR_PEL_DATA, val);
- outb(WRIT_COLR_PEL_DATA, val);
- outb(WRIT_COLR_PEL_DATA, val);
-
- val = EV_SCALE_BRIGHTNESS(level, BLACK_PALETTE_VALUE);
- outb(WRIT_COLR_PEL_AWMR, (unsigned char)BLACK_INDEX);
- outb(WRIT_COLR_PEL_DATA, val);
- outb(WRIT_COLR_PEL_DATA, val);
- outb(WRIT_COLR_PEL_DATA, val);
- }
-
-
- static void setColorMapToLinearMonochrome()
- // Description: Sets the color map to linear monochrome by zeroing
- // out the entire table, then setting the first four
- // palette values correctly.
- {
- int i;
-
- for (i = 0; i < 256; i++) {
- outb(WRIT_COLR_PEL_AWMR, i);
- outb(WRIT_COLR_PEL_DATA, 0x00);
- outb(WRIT_COLR_PEL_DATA, 0x00);
- outb(WRIT_COLR_PEL_DATA, 0x00);
- }
- outb(WRIT_COLR_PEL_AWMR, WHITE_INDEX);
- outb(WRIT_COLR_PEL_DATA, WHITE_PALETTE_VALUE);
- outb(WRIT_COLR_PEL_DATA, WHITE_PALETTE_VALUE);
- outb(WRIT_COLR_PEL_DATA, WHITE_PALETTE_VALUE);
-
- outb(WRIT_COLR_PEL_AWMR, LIGHT_GRAY_INDEX);
- outb(WRIT_COLR_PEL_DATA, LIGHT_GRAY_PALETTE_VALUE);
- outb(WRIT_COLR_PEL_DATA, LIGHT_GRAY_PALETTE_VALUE);
- outb(WRIT_COLR_PEL_DATA, LIGHT_GRAY_PALETTE_VALUE);
-
- outb(WRIT_COLR_PEL_AWMR, DARK_GRAY_INDEX);
- outb(WRIT_COLR_PEL_DATA, DARK_GRAY_PALETTE_VALUE);
- outb(WRIT_COLR_PEL_DATA, DARK_GRAY_PALETTE_VALUE);
- outb(WRIT_COLR_PEL_DATA, DARK_GRAY_PALETTE_VALUE);
-
- outb(WRIT_COLR_PEL_AWMR, BLACK_INDEX);
- outb(WRIT_COLR_PEL_DATA, BLACK_PALETTE_VALUE);
- outb(WRIT_COLR_PEL_DATA, BLACK_PALETTE_VALUE);
- outb(WRIT_COLR_PEL_DATA, BLACK_PALETTE_VALUE);
- }
-
-
- - (void) _selectMode
- // Description: During initialization, this selects the configured mode
- // and sets the display info accordingly.
- {
- selectedMode = [self selectMode:modeTable count:modeTableCount valid:NULL];
-
- if (selectedMode < 0) {
- IOLog("%s: Sorry, cannot use requested display mode.\n", [self name]);
- selectedMode = 0;
- }
-
- *[self displayInfo] = modeTable[selectedMode];
- }
-
-
- - (void)_SVGASetGeneralRegistersForMode:
- (const CirrusLogicGD542XMode *)cirrusLogicGD542XMode
- // Description: Set all the general registers for the given mode.
- {
- const SVGAIndexValuePair *regInfo;
-
- regInfo = cirrusLogicGD542XMode->generalRegisters;
- while (regInfo->index != -1) {
- outb(WRIT_EIDR_GEN_MISC_OP, regInfo->value);
- regInfo++;
- }
- }
-
-
- - (void)_SVGASetSequencerRegistersForMode:
- (const CirrusLogicGD542XMode *)cirrusLogicGD542XMode
- // Description: Set all the sequencer registers for the given mode.
- {
- const SVGAIndexValuePair *regInfo;
-
- regInfo = cirrusLogicGD542XMode->sequencerRegisters;
- while (regInfo->index != -1) {
- IOWriteRegister(EIDR_SEQ_ADDR, (char)(regInfo->index), regInfo->value);
- regInfo++;
- }
- }
-
-
- - (void)_SVGASetCrtControllerRegistersForMode:
- (const CirrusLogicGD542XMode *)cirrusLogicGD542XMode
- // Description: Set all the crt controller registers for the given mode.
- {
- const SVGAIndexValuePair *regInfo;
-
- regInfo = cirrusLogicGD542XMode->crtControllerRegisters;
- while (regInfo->index != -1) {
- IOWriteRegister(COLR_CRT_ADDR, (char)(regInfo->index), regInfo->value);
- regInfo++;
- }
- }
-
-
- - (void)_SVGASetGraphicsControllerRegistersForMode:
- (const CirrusLogicGD542XMode *)cirrusLogicGD542XMode
- // Description: Set all the graphics controller registers for the given mode.
- {
- const SVGAIndexValuePair *regInfo;
-
- regInfo = cirrusLogicGD542XMode->graphicsControllerRegisters;
- while (regInfo->index != -1) {
- IOWriteRegister(EIDR_GCR_ADDR, (char)(regInfo->index), regInfo->value);
- regInfo++;
- }
- }
-
-
- - (void)_SVGASetAttributeControllerRegistersForMode:
- (const CirrusLogicGD542XMode *)cirrusLogicGD542XMode
- // Description: Set all the attribute controller registers for the given mode.
- {
- const SVGAIndexValuePair *regInfo;
-
- regInfo = cirrusLogicGD542XMode->attributeControllerRegisters;
- while (regInfo->index != -1) {
- char tmpi;
- inb(READ_COLR_GEN_IN_ST_1);
- tmpi = inb(READ_TOGL_ACR_ADDR);
- tmpi &= ~ACR_MSK;
- tmpi |= (regInfo->index & ACR_MSK);
- outb(WRIT_TOGL_ACR_ADDR, tmpi);
- outb(WRIT_TOGL_ACR_DATA, regInfo->value);
- regInfo++;
- }
- }
-
-
- //
- // END: Implementation of private routines for SVGA
- //
-
-
- //
- // BEGIN: EXPORTED methods
- //
-
-
- - (void)setReadSegment: (unsigned char)segmentNum
- // Description: Select which 64K segment we intend to read from.
- {
- outb(0x03ce,0x09);
- outb(0x03cf,(segmentNum << 4));
- }
-
-
- - (void)setWriteSegment: (unsigned char)segmentNum
- // Description: Select which 64K segment we intend to write to.
- {
- outb(0x03ce,0x09);
- outb(0x03cf,(segmentNum << 4));
- }
-
-
- - (void)setReadPlane: (unsigned char)planeNum
- // Description: Select which of 4 bit planes to read from in planar
- // modes - only one plane can be active at a time.
- {
- char tmp;
-
- /* Select plane we are reading from */
- tmp = IOReadRegister(EIDR_GCR_ADDR, GCR_AT_READ_MAPS);
- tmp &= ~GCR_AT_RMS;
- tmp |= (planeNum & GCR_AT_RMS);
- IOWriteRegister(EIDR_GCR_ADDR, GCR_AT_READ_MAPS, tmp);
- }
-
-
- - (void)setWritePlane: (unsigned char)planeNum
- // Description: Select one of 4 bit planes to write to in planar modes.
- // Although more than one plane can be active at a time,
- // this routine only allows access to 1 plane at a time.
- {
- char tmp, plane = 0x01;
-
- //
- // Convert plane num to bit enable.
- //
- plane = plane << (planeNum & 0x03);
-
- //
- // Select plane we are writing to
- //
- tmp = IOReadRegister(EIDR_SEQ_ADDR, SEQ_AT_MPK);
- tmp &= ~(SEQ_AT_EM3 | SEQ_AT_EM2 | SEQ_AT_EM1 | SEQ_AT_EM0);
- tmp |= plane;
- IOWriteRegister(EIDR_SEQ_ADDR, SEQ_AT_MPK, tmp);
- }
-
-
- - (void)savePlaneAndSegmentSettings
- // Description: Saves the current plane and segment settings.
- // This is not a stack push, so we can only save/
- // restore one group of settings at a time.
- {
- writePlaneMask = IOReadRegister(EIDR_SEQ_ADDR, SEQ_AT_MPK);
- readPlaneMask = IOReadRegister(EIDR_GCR_ADDR, GCR_AT_READ_MAPS);
- outb(0x3ce,0x09);
- readSegment = inb(0x3cf);
- writeSegment=readSegment=(readSegment >> 4);
- }
-
-
- - (void)restorePlaneAndSegmentSettings
- // Description: Restores the current plane and segment settings.
- // This is not a stack pop, so we can only save/
- // restore one group of settings at a time.
- {
- IOWriteRegister(EIDR_SEQ_ADDR, SEQ_AT_MPK, writePlaneMask);
- IOWriteRegister(EIDR_GCR_ADDR, GCR_AT_READ_MAPS, readPlaneMask);
- outb(0x3ce, 0x09);
- outb(0x3cf, (readSegment << 4));
- }
-
-
- - (void)enterSVGAMode
- // Description: Put the display into SVGA mode selectedMode. This
- // typically happens when the window server starts running.
- // We set up all the registers necessary for the given
- // mode and then clear the screen.
- {
- IODisplayInfo *displayInfo;
- int totalScreenBytes, bytesLeftToClear, writeSegmentToClear;
-
- [self _SVGASetGeneralRegistersForMode:
- modeTable[selectedMode].parameters];
- [self _SVGASetSequencerRegistersForMode:
- modeTable[selectedMode].parameters];
- [self _SVGASetCrtControllerRegistersForMode:
- modeTable[selectedMode].parameters];
- [self _SVGASetGraphicsControllerRegistersForMode:
- modeTable[selectedMode].parameters];
- [self _SVGASetAttributeControllerRegistersForMode:
- modeTable[selectedMode].parameters];
-
- //
- // re-enable timing sequencer
- //
- IOWriteRegister(EIDR_SEQ_ADDR, SEQ_AT_CRS, 0x00);
- setColorMapToLinearMonochrome();
-
- //
- // Clear the screen.
- //
- displayInfo = [self displayInfo];
- totalScreenBytes = displayInfo->rowBytes * displayInfo->height;
- for ( bytesLeftToClear = totalScreenBytes, writeSegmentToClear = 0;
- bytesLeftToClear > 0;
- bytesLeftToClear -= 0x20000, writeSegmentToClear++) {
- [self setWriteSegment:writeSegmentToClear];
- memset(displayInfo->frameBuffer, 0, MIN(0x20000, bytesLeftToClear));
- }
-
- [self setWriteSegment:0];
- }
-
-
- - (void)revertToVGAMode
- // Description: Put the display into VGA mode. This typically happens
- // when SoftPC enters full-screen mode. We set up all the
- // registers necessary for the given mode.
- {
- outb(WRIT_EIDR_GEN_MISC_OP, 0xE3);
- }
-
-
- - initFromDeviceDescription:deviceDescription
- // Description: IODevice method. Initialize the current instance as
- // per the deviceDescription. Most importantly, this
- // includes selecting the mode and mapping the frame buffer.
- {
- IODisplayInfo *displayInfo;
- const IORange *range;
- const CirrusLogicGD542XMode *cirrusLogicGD542XMode;
-
- if ([super initFromDeviceDescription:deviceDescription] == nil)
- return [super free];
-
- [self _selectMode];
-
- range = [deviceDescription memoryRangeList];
- if (range == 0) {
- IOLog("%s: No memory range set.\n", [self name]);
- return [super free];
- }
- videoRamAddress = range[0].start;
-
- displayInfo = [self displayInfo];
- cirrusLogicGD542XMode = displayInfo->parameters;
-
- displayInfo->frameBuffer =
- (void *)[self mapFrameBufferAtPhysicalAddress:videoRamAddress
- length:0x20000]; //SCOTT--fix this
-
- if (displayInfo->frameBuffer == 0)
- return [super free];
-
- IOLog("%s: Initialized `%s' @ %d Hz.\n", [self name],
- cirrusLogicGD542XMode->name, displayInfo->refreshRate);
-
- return self;
- }
-
-
- - setBrightness:(int)level token:(int)t
- // Description: This is from the evScreen protocol. We override our superclass
- // on this since it doesn't know how to set our brightness.
- {
- if ( level < EV_SCREEN_MIN_BRIGHTNESS
- || level > EV_SCREEN_MAX_BRIGHTNESS )
- {
- IOLog("%s: Invalid arg to setBrightness:%d\n",
- [self name], level );
-
- if (level < EV_SCREEN_MIN_BRIGHTNESS) {
- level = EV_SCREEN_MIN_BRIGHTNESS;
- } else {
- level = EV_SCREEN_MAX_BRIGHTNESS;
- }
- }
- SetBrightness(level);
-
- return self;
- }
-
-
- //
- // END: EXPORTED methods
- //
-
- @end
-