home *** CD-ROM | disk | FTP | other *** search
/ NeXTSTEP 3.3 (Developer) / NeXT_Developer-3.3.iso / NextDeveloper / Examples / DriverKit / TsengLabsET4000 / TsengLabsET4000_reloc.tproj / TsengLabsET4000.m < prev    next >
Encoding:
Text File  |  1993-08-07  |  19.4 KB  |  668 lines

  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
  668.