|
|
1.1 ! root 1: /* Copyright (c) 1992 NeXT Computer, Inc. All rights reserved. ! 2: * ! 3: * TsengLabsET4000.m ! 4: * ! 5: */ ! 6: ! 7: ! 8: #import <driverkit/i386/IOEISADeviceDescription.h> ! 9: #import "TsengLabsET4000.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 _TsengLabsET4000Mode { ! 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: } TsengLabsET4000Mode; ! 41: ! 42: ! 43: /*************************************** ! 44: * TsengLabsET4000_1024x768x2x60hz mode ! 45: ***************************************/ ! 46: ! 47: static const SVGAIndexValuePair ! 48: TsengLabsET4000_1024x768x2x60hz_generalRegisters[] = { ! 49: {0, 0x3F}, ! 50: {-1, 0} ! 51: }; ! 52: ! 53: static const SVGAIndexValuePair ! 54: TsengLabsET4000_1024x768x2x60hz_sequencerRegisters[] = { ! 55: {0, 0x03}, {1, 0x01}, {2, 0x0F}, {3, 0x00}, {4, 0x06}, ! 56: {6, 0x00}, {7, 0xBC}, ! 57: {-1, 0} ! 58: }; ! 59: ! 60: static const SVGAIndexValuePair ! 61: TsengLabsET4000_1024x768x2x60hz_crtControllerRegisters[] = { ! 62: {0x11,0x00}, // Turn off lock allowing changing 0..7 ! 63: {0x00,0xA1}, {0x01,0x7F}, {0x02,0x80}, {0x03,0x04}, {0x04,0x88}, ! 64: {0x05,0x9E}, {0x06,0x26}, {0x07,0xFD}, {0x08,0x00}, {0x09,0x60}, ! 65: {0x0A,0x00}, {0x0B,0x00}, {0x0C,0x00}, {0x0D,0x00}, {0x0E,0x00}, ! 66: {0x0F,0x00}, {0x10,0x08}, {0x11,0x8A}, {0x12,0xFF}, {0x13,0x40}, ! 67: {0x14,0x00}, {0x15,0x04}, {0x16,0x22}, {0x17,0xC3}, {0x18,0xFF}, ! 68: {0x33,0x00}, {0x35,0x00}, ! 69: {-1, 0} ! 70: }; ! 71: ! 72: static const SVGAIndexValuePair ! 73: TsengLabsET4000_1024x768x2x60hz_graphicsControllerRegisters[] = { ! 74: {0x00,0x00}, {0x01,0x00}, {0x02,0x00}, {0x03,0x00}, {0x04,0x00}, ! 75: {0x05,0x00}, {0x06,0x05}, {0x07,0x0F}, {0x08,0xFF}, ! 76: {-1, 0} ! 77: }; ! 78: ! 79: static const SVGAIndexValuePair ! 80: TsengLabsET4000_1024x768x2x60hz_attributeControllerRegisters[] = { ! 81: {0x00,0x00}, {0x01,0x01}, {0x02,0x02}, {0x03,0x03}, {0x04,0x04}, ! 82: {0x05,0x05}, {0x06,0x14}, {0x07,0x07}, {0x08,0x38}, {0x09,0x39}, ! 83: {0x0A,0x3A}, {0x0B,0x3B}, {0x0C,0x3C}, {0x0D,0x3D}, {0x0E,0x3E}, ! 84: {0x0F,0x3F}, {0x10,0x01}, {0x11,0x00}, {0x12,0x0F}, {0x13,0x00}, ! 85: {0x14,0x00}, {0x16,0x00}, ! 86: {-1, 0} ! 87: }; ! 88: ! 89: ! 90: static const TsengLabsET4000Mode ! 91: TsengLabsET4000_1024x768x2x60hz = { ! 92: "1024x768x2x60hz", ! 93: TsengLabsET4000_1024x768x2x60hz_generalRegisters, ! 94: TsengLabsET4000_1024x768x2x60hz_sequencerRegisters, ! 95: TsengLabsET4000_1024x768x2x60hz_crtControllerRegisters, ! 96: TsengLabsET4000_1024x768x2x60hz_graphicsControllerRegisters, ! 97: TsengLabsET4000_1024x768x2x60hz_attributeControllerRegisters ! 98: }; ! 99: ! 100: ! 101: #if 0 /* TsengLabsET4000_800x600x2x60hz mode doesn't quite work */ ! 102: /************************************** ! 103: * TsengLabsET4000_800x600x2x60hz mode ! 104: **************************************/ ! 105: ! 106: static const SVGAIndexValuePair ! 107: TsengLabsET4000_800x600x2x60hz_generalRegisters[] = { ! 108: {0, 0xEF}, ! 109: {-1, 0} ! 110: }; ! 111: ! 112: static const SVGAIndexValuePair ! 113: TsengLabsET4000_800x600x2x60hz_sequencerRegisters[] = { ! 114: {0, 0x03}, {1, 0x01}, {2, 0x0F}, {3, 0x00}, {4, 0x06}, ! 115: {6, 0x00}, {7, 0xBC}, ! 116: {-1, 0} ! 117: }; ! 118: ! 119: static const SVGAIndexValuePair ! 120: TsengLabsET4000_800x600x2x60hz_crtControllerRegisters[] = { ! 121: {0x11,0x00}, // Turn off lock allowing changing 0..7 ! 122: {0x00,0x7F}, {0x01,0x63}, {0x02,0x64}, {0x03,0x02}, {0x04,0x64}, ! 123: {0x05,0x17}, {0x06,0x77}, {0x07,0xF0}, {0x08,0x00}, {0x09,0x60}, ! 124: {0x0A,0x00}, {0x0B,0x00}, {0x0C,0x00}, {0x0D,0x00}, {0x0E,0x00}, ! 125: {0x0F,0x00}, {0x10,0x60}, {0x11,0x82}, {0x12,0x57}, {0x13,0x32}, ! 126: {0x14,0x00}, {0x15,0x5B}, {0x16,0x75}, {0x17,0xC3}, {0x18,0xFF}, ! 127: {0x33,0x00}, {0x35,0x00}, ! 128: {-1, 0} ! 129: }; ! 130: ! 131: static const SVGAIndexValuePair ! 132: TsengLabsET4000_800x600x2x60hz_graphicsControllerRegisters[] = { ! 133: {0x00,0x00}, {0x01,0x00}, {0x02,0x00}, {0x03,0x00}, {0x04,0x00}, ! 134: {0x05,0x00}, {0x06,0x05}, {0x07,0x0F}, {0x08,0xFF}, ! 135: {-1, 0} ! 136: }; ! 137: ! 138: static const SVGAIndexValuePair ! 139: TsengLabsET4000_800x600x2x60hz_attributeControllerRegisters[] = { ! 140: {0x00,0x00}, {0x01,0x01}, {0x02,0x02}, {0x03,0x03}, {0x04,0x04}, ! 141: {0x05,0x05}, {0x06,0x14}, {0x07,0x07}, {0x08,0x38}, {0x09,0x39}, ! 142: {0x0A,0x3A}, {0x0B,0x3B}, {0x0C,0x3C}, {0x0D,0x3D}, {0x0E,0x3E}, ! 143: {0x0F,0x3F}, {0x10,0x01}, {0x11,0x00}, {0x12,0x0F}, {0x13,0x00}, ! 144: {0x14,0x00}, {0x16,0x00}, ! 145: {-1, 0} ! 146: }; ! 147: ! 148: ! 149: static const TsengLabsET4000Mode ! 150: TsengLabsET4000_800x600x2x60hz = { ! 151: "800x600x2x60hz", ! 152: TsengLabsET4000_800x600x2x60hz_generalRegisters, ! 153: TsengLabsET4000_800x600x2x60hz_sequencerRegisters, ! 154: TsengLabsET4000_800x600x2x60hz_crtControllerRegisters, ! 155: TsengLabsET4000_800x600x2x60hz_graphicsControllerRegisters, ! 156: TsengLabsET4000_800x600x2x60hz_attributeControllerRegisters ! 157: }; ! 158: #endif /* TsengLabsET4000_800x600x2x60hz mode doesn't quite work */ ! 159: ! 160: ! 161: /************************************** ! 162: * TsengLabsET4000_640x480_VGA mode ! 163: **************************************/ ! 164: ! 165: static const SVGAIndexValuePair ! 166: TsengLabsET4000_640x480_VGA_generalRegisters[] = { ! 167: {0, 0xE3}, ! 168: {-1, 0} ! 169: }; ! 170: ! 171: static const SVGAIndexValuePair ! 172: TsengLabsET4000_640x480_VGA_sequencerRegisters[] = { ! 173: {0, 0x03}, {1, 0x01}, {2, 0x0F}, {3, 0x00}, {4, 0x06}, ! 174: {6, 0x00}, {7, 0xFC}, ! 175: {-1, 0} ! 176: }; ! 177: ! 178: static const SVGAIndexValuePair ! 179: TsengLabsET4000_640x480_VGA_crtControllerRegisters[] = { ! 180: {0x11,0x00}, // Turn off lock allowing changing 0..7, 35 ! 181: {0x35,0x00}, ! 182: {0x00,0x5F}, {0x01,0x4F}, {0x02,0x50}, {0x03,0x82}, {0x04,0x54}, ! 183: {0x05,0x80}, {0x06,0x0B}, {0x07,0x3E}, {0x08,0x00}, {0x09,0x40}, ! 184: {0x0A,0x00}, {0x0B,0x00}, {0x0C,0x00}, {0x0D,0x00}, {0x0E,0x00}, ! 185: {0x0F,0x00}, {0x10,0xEA}, {0x11,0x8C}, {0x12,0xDF}, {0x13,0x28}, ! 186: {0x14,0x00}, {0x15,0xE7}, {0x16,0x04}, {0x17,0xE3}, {0x18,0xFF}, ! 187: {0x33,0x00}, ! 188: {-1, 0} ! 189: }; ! 190: ! 191: static const SVGAIndexValuePair ! 192: TsengLabsET4000_640x480_VGA_graphicsControllerRegisters[] = { ! 193: {0x00,0x00}, {0x01,0x00}, {0x02,0x00}, {0x03,0x00}, {0x04,0x00}, ! 194: {0x05,0x00}, {0x06,0x05}, {0x07,0x0F}, {0x08,0xFF}, ! 195: {-1, 0} ! 196: }; ! 197: ! 198: static const SVGAIndexValuePair ! 199: TsengLabsET4000_640x480_VGA_attributeControllerRegisters[] = { ! 200: {0x00,0x00}, {0x01,0x01}, {0x02,0x02}, {0x03,0x03}, {0x04,0x04}, ! 201: {0x05,0x05}, {0x06,0x14}, {0x07,0x07}, {0x08,0x38}, {0x09,0x39}, ! 202: {0x0A,0x3A}, {0x0B,0x3B}, {0x0C,0x3C}, {0x0D,0x3D}, {0x0E,0x3E}, ! 203: {0x0F,0x3F}, {0x10,0x01}, {0x11,0x00}, {0x12,0x0F}, {0x13,0x00}, ! 204: {0x14,0x00}, {0x16,0x00}, ! 205: {-1, 0} ! 206: }; ! 207: ! 208: ! 209: static const TsengLabsET4000Mode ! 210: TsengLabsET4000_640x480_VGA = { ! 211: "800x600x2x60hz", ! 212: TsengLabsET4000_640x480_VGA_generalRegisters, ! 213: TsengLabsET4000_640x480_VGA_sequencerRegisters, ! 214: TsengLabsET4000_640x480_VGA_crtControllerRegisters, ! 215: TsengLabsET4000_640x480_VGA_graphicsControllerRegisters, ! 216: TsengLabsET4000_640x480_VGA_attributeControllerRegisters ! 217: }; ! 218: ! 219: ! 220: /************************************** ! 221: * Framebuffer characteristics. ! 222: **************************************/ ! 223: ! 224: #define FRAMEBUFFER_ADDRESS ((void *) 0xa0000) ! 225: ! 226: static const IODisplayInfo modeTable[] = { ! 227: { ! 228: // ! 229: // TsengLabsET4000 1024 x 768 x 2 x 60hz ! 230: // ! 231: 1024, 768, 1024, ! 232: ! 233: // ! 234: // rowbytes = ! 235: // #bytes/scanline = ! 236: // ((pixels/line) * (2 bits/pixel) * (byte/8 bits)) = ! 237: // (pixel width / 4) ! 238: // ! 239: 256, 60, 0, IO_2BitsPerPixel, IO_OneIsBlackColorSpace, ! 240: "WW", 0, (void *)&TsengLabsET4000_1024x768x2x60hz ! 241: }, ! 242: #if 0 /* TsengLabsET4000_800x600x2x60hz mode doesn't quite work */ ! 243: { ! 244: // ! 245: // TsengLabsET4000 800 x 600 x 2 x 60hz ! 246: // ! 247: 800, 600, 800, 200, 60, 0, IO_2BitsPerPixel, IO_OneIsBlackColorSpace, ! 248: ! 249: // ! 250: // rowbytes = ! 251: // #bytes/scanline = ! 252: // ((pixels/line) * (2 bits/pixel) * (byte/8 bits)) = ! 253: // (pixel width / 4) ! 254: // ! 255: "WW", 0, (void *)&TsengLabsET4000_800x600x2x60hz ! 256: } ! 257: #endif /* TsengLabsET4000_800x600x2x60hz mode doesn't quite work */ ! 258: ! 259: /* Add more modes here. */ ! 260: }; ! 261: #define modeTableCount (sizeof(modeTable) / sizeof(IODisplayInfo)) ! 262: ! 263: ! 264: @implementation TsengLabsET4000 ! 265: ! 266: ! 267: // ! 268: // BEGIN: Implementation of private routines for SVGA ! 269: // ! 270: ! 271: ! 272: static void SetBrightness(unsigned int level) ! 273: // Description: Sets the screen's brightness. This implementation ! 274: // uses a fixed gamma value. It sets the palette ! 275: // values according to the brightness level. ! 276: { ! 277: unsigned char val; ! 278: ! 279: val = EV_SCALE_BRIGHTNESS(level, WHITE_PALETTE_VALUE); ! 280: outb(WRIT_COLR_PEL_AWMR, (unsigned char)WHITE_INDEX); ! 281: outb(WRIT_COLR_PEL_DATA, val); ! 282: outb(WRIT_COLR_PEL_DATA, val); ! 283: outb(WRIT_COLR_PEL_DATA, val); ! 284: ! 285: val = EV_SCALE_BRIGHTNESS(level, LIGHT_GRAY_PALETTE_VALUE); ! 286: outb(WRIT_COLR_PEL_AWMR, (unsigned char)LIGHT_GRAY_INDEX); ! 287: outb(WRIT_COLR_PEL_DATA, val); ! 288: outb(WRIT_COLR_PEL_DATA, val); ! 289: outb(WRIT_COLR_PEL_DATA, val); ! 290: ! 291: val = EV_SCALE_BRIGHTNESS(level, DARK_GRAY_PALETTE_VALUE); ! 292: outb(WRIT_COLR_PEL_AWMR, (unsigned char)DARK_GRAY_INDEX); ! 293: outb(WRIT_COLR_PEL_DATA, val); ! 294: outb(WRIT_COLR_PEL_DATA, val); ! 295: outb(WRIT_COLR_PEL_DATA, val); ! 296: ! 297: val = EV_SCALE_BRIGHTNESS(level, BLACK_PALETTE_VALUE); ! 298: outb(WRIT_COLR_PEL_AWMR, (unsigned char)BLACK_INDEX); ! 299: outb(WRIT_COLR_PEL_DATA, val); ! 300: outb(WRIT_COLR_PEL_DATA, val); ! 301: outb(WRIT_COLR_PEL_DATA, val); ! 302: } ! 303: ! 304: ! 305: static void setColorMapToLinearMonochrome() ! 306: // Description: Sets the color map to linear monochrome by zeroing ! 307: // out the entire table, then setting the first four ! 308: // palette values correctly. ! 309: { ! 310: int i; ! 311: ! 312: for (i = 0; i < 256; i++) { ! 313: outb(WRIT_COLR_PEL_AWMR, i); ! 314: outb(WRIT_COLR_PEL_DATA, 0x00); ! 315: outb(WRIT_COLR_PEL_DATA, 0x00); ! 316: outb(WRIT_COLR_PEL_DATA, 0x00); ! 317: } ! 318: outb(WRIT_COLR_PEL_AWMR, WHITE_INDEX); ! 319: outb(WRIT_COLR_PEL_DATA, WHITE_PALETTE_VALUE); ! 320: outb(WRIT_COLR_PEL_DATA, WHITE_PALETTE_VALUE); ! 321: outb(WRIT_COLR_PEL_DATA, WHITE_PALETTE_VALUE); ! 322: ! 323: outb(WRIT_COLR_PEL_AWMR, LIGHT_GRAY_INDEX); ! 324: outb(WRIT_COLR_PEL_DATA, LIGHT_GRAY_PALETTE_VALUE); ! 325: outb(WRIT_COLR_PEL_DATA, LIGHT_GRAY_PALETTE_VALUE); ! 326: outb(WRIT_COLR_PEL_DATA, LIGHT_GRAY_PALETTE_VALUE); ! 327: ! 328: outb(WRIT_COLR_PEL_AWMR, DARK_GRAY_INDEX); ! 329: outb(WRIT_COLR_PEL_DATA, DARK_GRAY_PALETTE_VALUE); ! 330: outb(WRIT_COLR_PEL_DATA, DARK_GRAY_PALETTE_VALUE); ! 331: outb(WRIT_COLR_PEL_DATA, DARK_GRAY_PALETTE_VALUE); ! 332: ! 333: outb(WRIT_COLR_PEL_AWMR, BLACK_INDEX); ! 334: outb(WRIT_COLR_PEL_DATA, BLACK_PALETTE_VALUE); ! 335: outb(WRIT_COLR_PEL_DATA, BLACK_PALETTE_VALUE); ! 336: outb(WRIT_COLR_PEL_DATA, BLACK_PALETTE_VALUE); ! 337: } ! 338: ! 339: ! 340: - (void) _selectMode ! 341: // Description: During initialization, this selects the configured mode ! 342: // and sets the display info accordingly. ! 343: { ! 344: selectedMode = [self selectMode:modeTable count:modeTableCount valid:NULL]; ! 345: ! 346: if (selectedMode < 0) { ! 347: IOLog("%s: Sorry, cannot use requested display mode.\n", [self name]); ! 348: selectedMode = 0; ! 349: } ! 350: ! 351: *[self displayInfo] = modeTable[selectedMode]; ! 352: } ! 353: ! 354: ! 355: - (void)_vgaTsKey ! 356: // Description: QUESTION ! 357: { ! 358: outb(WRIT_HERCULES_REG,0x03); ! 359: outb(WRIT_COLR_MODE_CT,0xA0); ! 360: } ! 361: ! 362: ! 363: - (void)_SVGASetGeneralRegistersForMode: ! 364: (const TsengLabsET4000Mode *)tsengLabsET4000Mode ! 365: // Description: Set all the general registers for the given mode. ! 366: { ! 367: const SVGAIndexValuePair *regInfo; ! 368: ! 369: regInfo = tsengLabsET4000Mode->generalRegisters; ! 370: while (regInfo->index != -1) { ! 371: outb(WRIT_EIDR_GEN_MISC_OP, regInfo->value); ! 372: regInfo++; ! 373: } ! 374: } ! 375: ! 376: ! 377: - (void)_SVGASetSequencerRegistersForMode: ! 378: (const TsengLabsET4000Mode *)tsengLabsET4000Mode ! 379: // Description: Set all the sequencer registers for the given mode. ! 380: { ! 381: const SVGAIndexValuePair *regInfo; ! 382: ! 383: regInfo = tsengLabsET4000Mode->sequencerRegisters; ! 384: while (regInfo->index != -1) { ! 385: if (regInfo->index == 1) { ! 386: [self _vgaTsKey]; ! 387: } ! 388: IOWriteRegister(EIDR_SEQ_ADDR, (char)(regInfo->index), regInfo->value); ! 389: regInfo++; ! 390: } ! 391: } ! 392: ! 393: ! 394: - (void)_SVGASetCrtControllerRegistersForMode: ! 395: (const TsengLabsET4000Mode *)tsengLabsET4000Mode ! 396: // Description: Set all the crt controller registers for the given mode. ! 397: { ! 398: const SVGAIndexValuePair *regInfo; ! 399: ! 400: regInfo = tsengLabsET4000Mode->crtControllerRegisters; ! 401: while (regInfo->index != -1) { ! 402: IOWriteRegister(COLR_CRT_ADDR, (char)(regInfo->index), regInfo->value); ! 403: regInfo++; ! 404: } ! 405: } ! 406: ! 407: ! 408: - (void)_SVGASetGraphicsControllerRegistersForMode: ! 409: (const TsengLabsET4000Mode *)tsengLabsET4000Mode ! 410: // Description: Set all the graphics controller registers for the given mode. ! 411: { ! 412: const SVGAIndexValuePair *regInfo; ! 413: ! 414: regInfo = tsengLabsET4000Mode->graphicsControllerRegisters; ! 415: while (regInfo->index != -1) { ! 416: IOWriteRegister(EIDR_GCR_ADDR, (char)(regInfo->index), regInfo->value); ! 417: regInfo++; ! 418: } ! 419: } ! 420: ! 421: ! 422: - (void)_SVGASetAttributeControllerRegistersForMode: ! 423: (const TsengLabsET4000Mode *)tsengLabsET4000Mode ! 424: // Description: Set all the attribute controller registers for the given mode. ! 425: { ! 426: const SVGAIndexValuePair *regInfo; ! 427: ! 428: regInfo = tsengLabsET4000Mode->attributeControllerRegisters; ! 429: while (regInfo->index != -1) { ! 430: char tmpi; ! 431: inb(READ_COLR_GEN_IN_ST_1); ! 432: tmpi = inb(READ_TOGL_ACR_ADDR); ! 433: tmpi &= ~ACR_MSK; ! 434: tmpi |= (regInfo->index & ACR_MSK); ! 435: outb(WRIT_TOGL_ACR_ADDR, tmpi); ! 436: outb(WRIT_TOGL_ACR_DATA, regInfo->value); ! 437: regInfo++; ! 438: } ! 439: } ! 440: ! 441: ! 442: // ! 443: // END: Implementation of private routines for SVGA ! 444: // ! 445: ! 446: ! 447: // ! 448: // BEGIN: EXPORTED methods ! 449: // ! 450: ! 451: ! 452: - (void)setReadSegment: (unsigned char)segmentNum ! 453: // Description: Select which 64K segment we intend to read from. ! 454: { ! 455: char tmp; ! 456: ! 457: tmp = inb(EIDR_GCR_SEGS); ! 458: tmp &= GCR_TS_GWR; ! 459: tmp |= ((segmentNum << 4) & GCR_TS_GRD); ! 460: outb(EIDR_GCR_SEGS, tmp); ! 461: } ! 462: ! 463: ! 464: - (void)setWriteSegment: (unsigned char)segmentNum ! 465: // Description: Select which 64K segment we intend to write to. ! 466: { ! 467: char tmp; ! 468: ! 469: tmp = inb(EIDR_GCR_SEGS); ! 470: tmp &= GCR_TS_GRD; ! 471: tmp |= (segmentNum & GCR_TS_GWR); ! 472: outb(EIDR_GCR_SEGS, tmp); ! 473: } ! 474: ! 475: ! 476: - (void)setReadPlane: (unsigned char)planeNum ! 477: // Description: Select which of 4 bit planes to read from in planar ! 478: // modes - only one plane can be active at a time. ! 479: { ! 480: char tmp; ! 481: ! 482: /* Select plane we are reading from */ ! 483: tmp = IOReadRegister(EIDR_GCR_ADDR, GCR_AT_READ_MAPS); ! 484: tmp &= ~GCR_AT_RMS; ! 485: tmp |= (planeNum & GCR_AT_RMS); ! 486: IOWriteRegister(EIDR_GCR_ADDR, GCR_AT_READ_MAPS, tmp); ! 487: } ! 488: ! 489: ! 490: - (void)setWritePlane: (unsigned char)planeNum ! 491: // Description: Select one of 4 bit planes to write to in planar modes. ! 492: // Although more than one plane can be active at a time, ! 493: // this routine only allows access to 1 plane at a time. ! 494: { ! 495: char tmp, plane = 0x01; ! 496: ! 497: // ! 498: // Convert plane num to bit enable. ! 499: // ! 500: plane = plane << (planeNum & 0x03); ! 501: ! 502: // ! 503: // Select plane we are writing to ! 504: // ! 505: tmp = IOReadRegister(EIDR_SEQ_ADDR, SEQ_AT_MPK); ! 506: tmp &= ~(SEQ_AT_EM3 | SEQ_AT_EM2 | SEQ_AT_EM1 | SEQ_AT_EM0); ! 507: tmp |= plane; ! 508: IOWriteRegister(EIDR_SEQ_ADDR, SEQ_AT_MPK, tmp); ! 509: } ! 510: ! 511: ! 512: - (void)savePlaneAndSegmentSettings ! 513: // Description: Saves the current plane and segment settings. ! 514: // This is not a stack push, so we can only save/ ! 515: // restore one group of settings at a time. ! 516: { ! 517: writePlaneMask = IOReadRegister(EIDR_SEQ_ADDR, SEQ_AT_MPK); ! 518: readPlaneMask = IOReadRegister(EIDR_GCR_ADDR, GCR_AT_READ_MAPS); ! 519: readSegment = inb(EIDR_GCR_SEGS); ! 520: writeSegment = inb(EIDR_GCR_SEGS); ! 521: } ! 522: ! 523: ! 524: - (void)restorePlaneAndSegmentSettings ! 525: // Description: Restores the current plane and segment settings. ! 526: // This is not a stack pop, so we can only save/ ! 527: // restore one group of settings at a time. ! 528: { ! 529: IOWriteRegister(EIDR_SEQ_ADDR, SEQ_AT_MPK, writePlaneMask); ! 530: IOWriteRegister(EIDR_GCR_ADDR, GCR_AT_READ_MAPS, readPlaneMask); ! 531: outb(EIDR_GCR_SEGS, readSegment); ! 532: outb(EIDR_GCR_SEGS, writeSegment); ! 533: } ! 534: ! 535: ! 536: - (void)enterSVGAMode ! 537: // Description: Put the display into SVGA mode selectedMode. This ! 538: // typically happens when the window server starts running. ! 539: // We set up all the registers necessary for the given ! 540: // mode and then clear the screen. ! 541: { ! 542: IODisplayInfo *displayInfo; ! 543: int totalScreenBytes, bytesLeftToClear, writeSegmentToClear; ! 544: ! 545: [self _vgaTsKey]; ! 546: [self _SVGASetGeneralRegistersForMode: ! 547: modeTable[selectedMode].parameters]; ! 548: [self _SVGASetSequencerRegistersForMode: ! 549: modeTable[selectedMode].parameters]; ! 550: [self _SVGASetCrtControllerRegistersForMode: ! 551: modeTable[selectedMode].parameters]; ! 552: [self _SVGASetGraphicsControllerRegistersForMode: ! 553: modeTable[selectedMode].parameters]; ! 554: [self _SVGASetAttributeControllerRegistersForMode: ! 555: modeTable[selectedMode].parameters]; ! 556: ! 557: // ! 558: // re-enable timing sequencer ! 559: // ! 560: IOWriteRegister(EIDR_SEQ_ADDR, SEQ_AT_CRS, 0x00); ! 561: setColorMapToLinearMonochrome(); ! 562: ! 563: // ! 564: // Clear the screen. ! 565: // ! 566: displayInfo = [self displayInfo]; ! 567: totalScreenBytes = displayInfo->rowBytes * displayInfo->height; ! 568: for ( bytesLeftToClear = totalScreenBytes, writeSegmentToClear = 0; ! 569: bytesLeftToClear > 0; ! 570: bytesLeftToClear -= 0x20000, writeSegmentToClear++) { ! 571: [self setWriteSegment:writeSegmentToClear]; ! 572: memset(displayInfo->frameBuffer, 0, MIN(0x20000, bytesLeftToClear)); ! 573: } ! 574: ! 575: [self setWriteSegment:0]; ! 576: } ! 577: ! 578: ! 579: - (void)revertToVGAMode ! 580: // Description: Put the display into VGA mode. This typically happens ! 581: // when SoftPC enters full-screen mode. We set up all the ! 582: // registers necessary for the given mode. ! 583: { ! 584: [self _vgaTsKey]; ! 585: [self _SVGASetGeneralRegistersForMode: ! 586: &TsengLabsET4000_640x480_VGA]; ! 587: [self _SVGASetSequencerRegistersForMode: ! 588: &TsengLabsET4000_640x480_VGA]; ! 589: [self _SVGASetCrtControllerRegistersForMode: ! 590: &TsengLabsET4000_640x480_VGA]; ! 591: [self _SVGASetGraphicsControllerRegistersForMode: ! 592: &TsengLabsET4000_640x480_VGA]; ! 593: [self _SVGASetAttributeControllerRegistersForMode: ! 594: &TsengLabsET4000_640x480_VGA]; ! 595: ! 596: // ! 597: // re-enable timing sequencer ! 598: // ! 599: IOWriteRegister(EIDR_SEQ_ADDR, SEQ_AT_CRS, 0x00); ! 600: } ! 601: ! 602: ! 603: - initFromDeviceDescription:deviceDescription ! 604: // Description: IODevice method. Initialize the current instance as ! 605: // per the deviceDescription. Most importantly, this ! 606: // includes selecting the mode and mapping the frame buffer. ! 607: { ! 608: IODisplayInfo *displayInfo; ! 609: const IORange *range; ! 610: const TsengLabsET4000Mode *tsengLabsET4000Mode; ! 611: ! 612: if ([super initFromDeviceDescription:deviceDescription] == nil) ! 613: return [super free]; ! 614: ! 615: [self _selectMode]; ! 616: ! 617: range = [deviceDescription memoryRangeList]; ! 618: if (range == 0) { ! 619: IOLog("%s: No memory range set.\n", [self name]); ! 620: return [super free]; ! 621: } ! 622: videoRamAddress = range[0].start; ! 623: ! 624: displayInfo = [self displayInfo]; ! 625: tsengLabsET4000Mode = displayInfo->parameters; ! 626: ! 627: displayInfo->frameBuffer = ! 628: (void *)[self mapFrameBufferAtPhysicalAddress:videoRamAddress ! 629: length:0x20000]; ! 630: ! 631: if (displayInfo->frameBuffer == 0) ! 632: return [super free]; ! 633: ! 634: IOLog("%s: Initialized `%s' @ %d Hz.\n", [self name], ! 635: tsengLabsET4000Mode->name, displayInfo->refreshRate); ! 636: ! 637: return self; ! 638: } ! 639: ! 640: ! 641: - setBrightness:(int)level token:(int)t ! 642: // Description: This is from the evScreen protocol. We override our superclass ! 643: // on this since it doesn't know how to set our brightness. ! 644: { ! 645: if ( level < EV_SCREEN_MIN_BRIGHTNESS ! 646: || level > EV_SCREEN_MAX_BRIGHTNESS ) ! 647: { ! 648: IOLog("%s: Invalid arg to setBrightness:%d\n", ! 649: [self name], level ); ! 650: ! 651: if (level < EV_SCREEN_MIN_BRIGHTNESS) { ! 652: level = EV_SCREEN_MIN_BRIGHTNESS; ! 653: } else { ! 654: level = EV_SCREEN_MAX_BRIGHTNESS; ! 655: } ! 656: } ! 657: SetBrightness(level); ! 658: ! 659: return self; ! 660: } ! 661: ! 662: ! 663: // ! 664: // END: EXPORTED methods ! 665: // ! 666: ! 667: @end
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.