diff --git a/src/add-ons/accelerants/s3savage/InitAccelerant.c b/src/add-ons/accelerants/s3savage/InitAccelerant.c index e070680ae8..6eb8d63e2b 100644 --- a/src/add-ons/accelerants/s3savage/InitAccelerant.c +++ b/src/add-ons/accelerants/s3savage/InitAccelerant.c @@ -142,10 +142,6 @@ INIT_ACCELERANT(int the_fd) /* count of issued parameters or commands */ si->engine.lastIdle = si->engine.count = 0; - /* set the cursor colors. You may or may not have to do this, depending - on the device. */ - SavageSetCursorColors(~0, 0); - /* ensure cursor state */ SHOW_CURSOR(false); diff --git a/src/add-ons/accelerants/s3savage/ProposeDisplayMode.c b/src/add-ons/accelerants/s3savage/ProposeDisplayMode.c index d2f8eefcb4..19f2341733 100644 --- a/src/add-ons/accelerants/s3savage/ProposeDisplayMode.c +++ b/src/add-ons/accelerants/s3savage/ProposeDisplayMode.c @@ -8,6 +8,8 @@ #include "GlobalData.h" #include "AccelerantPrototypes.h" +#include "savage.h" + #include @@ -17,8 +19,6 @@ static const display_mode mode_list[] = { { { 25175, 640, 656, 752, 800, 480, 490, 492, 525, 0}, B_CMAP8, 640, 480, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@60Hz_(640X480X8.Z1) */ - { { 27500, 640, 672, 768, 864, 480, 488, 494, 530, 0}, B_CMAP8, 640, 480, 0, 0, MODE_FLAGS}, /* 640X480X60Hz */ - { { 30500, 640, 672, 768, 864, 480, 517, 523, 588, 0}, B_CMAP8, 640, 480, 0, 0, MODE_FLAGS}, /* SVGA_640X480X60HzNI */ { { 31500, 640, 664, 704, 832, 480, 489, 492, 520, 0}, B_CMAP8, 640, 480, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@70-72Hz_(640X480X8.Z1) */ { { 31500, 640, 656, 720, 840, 480, 481, 484, 500, 0}, B_CMAP8, 640, 480, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@75Hz_(640X480X8.Z1) */ { { 36000, 640, 696, 752, 832, 480, 481, 484, 509, 0}, B_CMAP8, 640, 480, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@85Hz_(640X480X8.Z1) */ @@ -35,6 +35,7 @@ static const display_mode mode_list[] = { { { 78750, 1024, 1040, 1136, 1312, 768, 769, 772, 800, T_POSITIVE_SYNC}, B_CMAP8, 1024, 768, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@75Hz_(1024X768X8.Z1) */ { { 94500, 1024, 1072, 1168, 1376, 768, 769, 772, 808, T_POSITIVE_SYNC}, B_CMAP8, 1024, 768, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@85Hz_(1024X768X8.Z1) */ + { { 81642, 1152, 1216, 1336, 1520, 864, 865, 868, 895, T_POSITIVE_SYNC}, B_CMAP8, 1152, 864, 0, 0, MODE_FLAGS}, // 1152x864x60Hz { { 94200, 1152, 1184, 1280, 1472, 864, 865, 868, 914, T_POSITIVE_SYNC}, B_CMAP8, 1152, 864, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@70Hz_(1152X864X8.Z1) */ { { 97800, 1152, 1216, 1344, 1552, 864, 865, 868, 900, T_POSITIVE_SYNC}, B_CMAP8, 1152, 864, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@70Hz_(1152X864X8.Z1) */ { { 108000, 1152, 1216, 1344, 1600, 864, 865, 868, 900, T_POSITIVE_SYNC}, B_CMAP8, 1152, 864, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@75Hz_(1152X864X8.Z1) */ @@ -59,14 +60,13 @@ static const display_mode mode_list[] = { { { 218250, 1856, 1952, 2176, 2528, 1392, 1393, 1396, 1439, B_POSITIVE_VSYNC}, B_CMAP8, 1856, 1392, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@60Hz_(1856X1392) */ { { 288000, 1856, 1984, 2208, 2560, 1392, 1393, 1396, 1500, B_POSITIVE_VSYNC}, B_CMAP8, 1856, 1392, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@75Hz_(1856X1392) */ + + // widescreen resolutions, 16:10 + { { 83500, 1280, 1344, 1480, 1680, 800, 801, 804, 828, T_POSITIVE_SYNC}, B_CMAP8, 1280, 800, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@60Hz_(1280X800) */ + { { 106500, 1440, 1520, 1672, 1904, 900, 901, 904, 932, T_POSITIVE_SYNC}, B_CMAP8, 1440, 900, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@60Hz_(1440X900) */ - { { 234000, 1920, 2048, 2256, 2600, 1440, 1441, 1444, 1500, B_POSITIVE_VSYNC}, B_CMAP8, 1920, 1440, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@60Hz_(1920X1440) */ - { { 297000, 1920, 2064, 2288, 2640, 1440, 1441, 1444, 1500, B_POSITIVE_VSYNC}, B_CMAP8, 1920, 1440, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@75Hz_(1920X1440) */ - { { 341350, 1920, 2072, 2288, 2656, 1440, 1441, 1444, 1512, B_POSITIVE_VSYNC}, B_CMAP8, 1920, 1440, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@85Hz_(1920X1440) */ - - { { 266950, 2048, 2200, 2424, 2800, 1536, 1537, 1540, 1589, B_POSITIVE_VSYNC}, B_CMAP8, 2048, 1536, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@60Hz_(2048x1536) */ - { { 340480, 2048, 2216, 2440, 2832, 1536, 1537, 1540, 1603, B_POSITIVE_VSYNC}, B_CMAP8, 2048, 1536, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@75Hz_(2048x1536) */ - { { 388040, 2048, 2216, 2440, 2832, 1536, 1537, 1540, 1612, B_POSITIVE_VSYNC}, B_CMAP8, 2048, 1536, 0, 0, MODE_FLAGS} /* Vesa_Monitor_@85Hz_(2048x1536) */ + // widescreen resolutions, 16:9 + { { 74520, 1280, 1368, 1424, 1656, 720, 724, 730, 750, T_POSITIVE_SYNC}, B_CMAP8, 1280, 720, 0, 0, MODE_FLAGS} /* Vesa_Monitor_@60Hz_(1280X720) */ }; @@ -213,12 +213,13 @@ PROPOSE_DISPLAY_MODE(display_mode *target, const display_mode *low, const displa result = B_BAD_VALUE; // If the video is connected directly to an LCD display (ie, notebook - // computer), restrict the display mode to the resolution of the LCD - // display. + // computer), restrict the display mode to resolutions where the width and + // height of the mode are less than or equal to the width and height of the + // LCD display. if (MT_LCD == si->displayType && si->panelX > 0 && si->panelY > 0 && - (target->timing.h_display != si->panelX - || target->timing.v_display != si->panelY)) { + (target->timing.h_display > si->panelX + || target->timing.v_display > si->panelY)) { return B_ERROR; } @@ -399,3 +400,19 @@ create_mode_list(void) return B_OK; } + +bool +IsDisplaySizeValid(int width, int height) +{ + // Search the mode list for a mode which has the width and height passed + // by the caller, and return true if a match is found. + + uint32 i; + + for (i = 0; i < MODE_COUNT; i++) { + if (mode_list[i].virtual_width == width && mode_list[i].virtual_height == height) + return true; + } + + return false; // match not found +} diff --git a/src/add-ons/accelerants/s3savage/savage.h b/src/add-ons/accelerants/s3savage/savage.h index fbb5b3b936..c1796844ea 100644 --- a/src/add-ons/accelerants/s3savage/savage.h +++ b/src/add-ons/accelerants/s3savage/savage.h @@ -245,8 +245,9 @@ typedef struct +bool IsDisplaySizeValid(int width, int height); + bool SavageLoadCursorImage(int width, int height, uint8* and_mask, uint8* xor_mask); -void SavageSetCursorColors(int bg, int fg); void SavageSetCursorPosition(int x, int y); void SavageShowCursor(void); void SavageHideCursor(void); diff --git a/src/add-ons/accelerants/s3savage/savage_cursor.c b/src/add-ons/accelerants/s3savage/savage_cursor.c index 9842021479..da74b4f3e4 100644 --- a/src/add-ons/accelerants/s3savage/savage_cursor.c +++ b/src/add-ons/accelerants/s3savage/savage_cursor.c @@ -1,8 +1,6 @@ /* - Haiku S3 Savage driver adapted from the original BeSavage driver by - Erdi Chen and the X.org Savage driver. + Haiku S3 Savage driver adapted from the X.org Savage driver. - Copyright 1999 Erdi Chen Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. Copyright (c) 2003-2006, X.Org Foundation @@ -101,7 +99,7 @@ SavageSetCursorPosition(int x, int y) } -void +static void SavageSetCursorColors(int bg, int fg) { /* With the streams engine on HW Cursor seems to be 24bpp ALWAYS */ @@ -127,74 +125,44 @@ SavageSetCursorColors(int bg, int fg) /* Assume width and height are byte-aligned. */ bool -SavageLoadCursorImage(int width, int height, uint8* and_mask, uint8* xor_mask) +SavageLoadCursorImage(int width, int height, uint8* andMask, uint8* xorMask) { - int i, x, y, bit_shift; - uint8 and_buf[64*64 / 8]; - uint8 xor_buf[64*64 / 8]; - uint8* and_ptr = and_mask; - uint8* xor_ptr = xor_mask; - uint16* pFB; + int i, colByte, row; + uint8* fbCursor; + uint16* fbCursor16; -//@ TRACE(("SavageLoadCursorImage\n")); +// TRACE(("SavageLoadCursorImage, width: %ld height: %ld\n", width, height)); - if ( ! and_mask || ! xor_mask) + if ( ! andMask || ! xorMask) return false; - bit_shift = width & 7; - width /= 8; - - if (width != 64 || height != 64) { - and_ptr = (uint8*)and_buf; - xor_ptr = (uint8*)xor_buf; - - for (y = 0; y < height; y++) { - for (x = 0; x < width; x++) { - *and_ptr++ = *and_mask++; - *xor_ptr++ = *xor_mask++; - } - - if (bit_shift) { - x++; - *and_ptr++ = 0xFF ^ ((*and_mask++) & (~(0xFF >> bit_shift))); - *xor_ptr++ = (*xor_mask++) & (~(0xFF >> bit_shift)); - } - - for (; x < 8; x++) { - *and_ptr++ = 0xFF; - *xor_ptr++ = 0x00; - } - } - - for (; y < 64; y++) { - *(uint32 *)and_ptr = ~0; - and_ptr += 4; - *(uint32 *)and_ptr = ~0; - and_ptr += 4; - *(uint32 *)xor_ptr = 0; - xor_ptr += 4; - *(uint32 *)xor_ptr = 0; - xor_ptr += 4; - } - - and_ptr = (uint8 *)and_buf; - xor_ptr = (uint8 *)xor_buf; + // Initialize the hardware cursor as completely transparent. + + fbCursor16 = (void *)((addr_t)si->videoMemAddr + si->cursorOffset); + + for (i = 0; i < 1024 / 4; i++) { + *fbCursor16++ = ~0; // and bits + *fbCursor16++ = 0; // xor bits } + + // Now load the AND & XOR masks for the cursor image into the cursor + // buffer. + + fbCursor = (void *)((addr_t)si->videoMemAddr + si->cursorOffset); + + for (row = 0; row < height; row++) { + for (colByte = 0; colByte < width / 8; colByte++) { + fbCursor[row * 16 + colByte] = *andMask++; + fbCursor[row * 16 + colByte + 2] = *xorMask++; + } + } + + SavageSetCursorColors(~0, 0); // set cursor colors to black & white /* Set cursor location in video memory. */ WriteCrtc(0x4d, (0xff & si->cursorOffset / 1024)); WriteCrtc(0x4c, (0xff00 & si->cursorOffset / 1024) >> 8); - pFB = (void *)((addr_t)si->videoMemAddr + si->cursorOffset); - - for (i = 0; i < 64 * 64 / 16; i++) { - *pFB++ = *(uint16*)and_ptr; - *pFB++ = *(uint16*)xor_ptr; - - and_ptr += 2; - xor_ptr += 2; - } - if (S3_SAVAGE4_SERIES(si->chipset)) { /* * Bug in Savage4 Rev B requires us to do an MMIO read after diff --git a/src/add-ons/accelerants/s3savage/savage_driver.c b/src/add-ons/accelerants/s3savage/savage_driver.c index e83b788b0f..3d21cdbc84 100644 --- a/src/add-ons/accelerants/s3savage/savage_driver.c +++ b/src/add-ons/accelerants/s3savage/savage_driver.c @@ -189,7 +189,8 @@ WaitIdleEmpty2K() } -static void SavageGetPanelInfo() +static void +SavageGetPanelInfo() { uint8 cr6b; int panelX, panelY; @@ -209,14 +210,20 @@ static void SavageGetPanelInfo() panelX = (ReadSeq(0x61) + ((ReadSeq(0x66) & 0x02) << 7) + 1) * 8; panelY = ReadSeq(0x69) + ((ReadSeq(0x6e) & 0x70) << 4) + 1; - /* OK, I admit it. I don't know how to limit the max dot clock - * for LCD panels of various sizes. I thought I copied the formula - * from the BIOS, but many users have informed me of my folly. - * - * Instead, I'll abandon any attempt to automatically limit the - * clock, and add an LCDClock option to XF86Config. Some day, - * I should come back to this. - */ + if ( ! IsDisplaySizeValid(panelX, panelY)) { + + // Some chips such as the Savage IX/MV in a Thinkpad T-22 will return + // a width that is 8 pixels too wide probably because reg SR61 is set + // to a value +1 higher than it should be. Subtract 8 from the width, + // and check if that is a valid width. + + panelX -= 8; + if ( ! IsDisplaySizeValid(panelX, panelY)) { + TRACE(("%dx%d LCD panel size invalid. No matching video mode\n", panelX + 8, panelY)); + si->displayType = MT_CRT; + return; + } + } if ((ReadSeq(0x39) & 0x03) == 0) sTechnology = "TFT"; @@ -229,7 +236,7 @@ static void SavageGetPanelInfo() cr6b & ActiveLCD ? "and active" : "but not active")); if (cr6b & ActiveLCD) { - TRACE(("Limiting video mode to %dx%d\n", panelX, panelY)); + TRACE(("Limiting max video mode to %dx%d\n", panelX, panelY)); si->panelX = panelX; si->panelY = panelY;