diff options
author | Robin Cutshaw <robin@intercore.com> | 1999-12-30 03:03:21 +0000 |
---|---|---|
committer | Robin Cutshaw <robin@intercore.com> | 1999-12-30 03:03:21 +0000 |
commit | 30e35cb44b6ea11d0eac8ce0d986517f3224852a (patch) | |
tree | a4bb0182dbcf5e4ce8cd61ed4e257815d9af3957 /hw/kdrive/savage | |
parent | f13b792a3a8d307a18cd6a41aa5a06622009e42f (diff) |
3516. Jumbo Tiny-X patch with Itsy support (#3527, Keith Packard).xf-3_9_17xf-3_9_16Za
Diffstat (limited to 'hw/kdrive/savage')
-rw-r--r-- | hw/kdrive/savage/s3.c | 1067 | ||||
-rw-r--r-- | hw/kdrive/savage/s3.h | 128 | ||||
-rw-r--r-- | hw/kdrive/savage/s3clock.c | 4 | ||||
-rw-r--r-- | hw/kdrive/savage/s3cmap.c | 52 | ||||
-rw-r--r-- | hw/kdrive/savage/s3curs.c | 75 | ||||
-rw-r--r-- | hw/kdrive/savage/s3draw.c | 314 | ||||
-rw-r--r-- | hw/kdrive/savage/s3draw.h | 107 | ||||
-rw-r--r-- | hw/kdrive/savage/s3gc.c | 86 | ||||
-rw-r--r-- | hw/kdrive/savage/s3reg.c | 117 | ||||
-rw-r--r-- | hw/kdrive/savage/s3reg.h | 29 | ||||
-rw-r--r-- | hw/kdrive/savage/s3stub.c | 37 |
11 files changed, 1415 insertions, 601 deletions
diff --git a/hw/kdrive/savage/s3.c b/hw/kdrive/savage/s3.c index bf3e2896a..debe5df43 100644 --- a/hw/kdrive/savage/s3.c +++ b/hw/kdrive/savage/s3.c @@ -22,7 +22,7 @@ * * Author: Keith Packard, SuSE, Inc. */ -/* $XFree86: $ */ +/* $XFree86: xc/programs/Xserver/hw/kdrive/savage/s3.c,v 1.1 1999/11/19 13:53:54 hohndel Exp $ */ #include "s3.h" @@ -30,141 +30,6 @@ #define PACKED_OFFSET (0x8100) #define IOMAP_OFFSET (0x8000) -/* - * Clock synthesis: - * - * f_out = f_ref * ((M + 2) / ((N + 2) * (1 << R))) - * - * Constraints: - * - * 1. 135MHz <= f_ref * ((M + 2) / (N + 2)) <= 270 MHz - * 2. N >= 1 - * - * Vertical refresh rate = clock / ((hsize + hblank) * (vsize + vblank)) - * Horizontal refresh rate = clock / (hsize + hblank) - */ - -#define DEFAULT_S3_TIMING 1 - -S3Timing s3Timings[] = { - /* FP BP BLANK */ - /* M N R blank bios5 */ - { 640, 480, 60, - 16, 48, 160, /* horizontal 31.321 KHz */ - 10, 33, 45, /* vertical 59.568 Hz */ - 26, 0, 3, /* pixel 25.057 MHz */ - }, - - { 800, 600, 85, - 32, 152, 248, /* horizontal 53.673 KHz */ - 1, 27, 31, /* vertical 85.060 Hz */ - 108, 5, 2, /* pixel 56.249 MHz */ - }, - { 800, 600, 75, - 16, 160, 256, /* horizontal 46.891 KHz */ - 1, 21, 25, /* vertical 75.025 Hz */ - 81, 4, 2, /* pixel 49.516 MHz */ - }, - { 800, 600, 72, - 56, 64, 240, /* horizontal 48.186 KHz */ - 37, 23, 66, /* vertical 72.351 Hz */ - 26, 0, 2, /* pixel 50.113 MHz */ - }, - { 800, 600, 60, - 48, 80, 256, - 1, 23, 28, - 0, 0, 0, - }, - { 1024, 768, 85, - 48, 208, 352, /* horizontal 68.676 KHz */ - 1, 36, 40, /* vertical 84.996 Hz */ - 64, 3, 1, /* pixel 94.499 MHz */ - }, - { 1024, 768, 75, - 16, 176, 288, /* horizontal 60.022 KHz */ - 1, 28, 32, /* vertical 75.028 Hz */ - 20, 0, 1, /* pixel 78.749 MHz */ - }, - { 1024, 768, 70, - 32, 136, 304, /* horizontal 56.604 KHz */ - 2, 30, 38, /* vertical 70.227 Hz */ - 124, 1, 3, /* pixel 75.170 MHz */ - }, - { 1024, 768, 66, - 24, 144, 304, /* horizontal 53.234 KHz */ - 3, 29, 38, /* vertical 66.047 Hz */ - 77, 6, 1, /* pixel 70.695 MHz */ - }, - - { 1152, 900, 85, - 48, 208, 384, /* horizontal 79.900 KHz */ - 1, 32, 38, /* vertical 85.181 Hz */ - 118, 5, 1, /* pixel 122.726 MHz */ - }, - { 1152, 900, 75, - 32, 208, 384, /* horizontal 70.495 Khz */ - 1, 32, 38, /* vertical 75.154 Hz */ - 119, 6, 1, /* pixel 108.280 MHz */ - }, - { 1152, 900, 70, - 32, 208, 384, /* horizontal 65.251 KHz */ - 2, 32, 38, /* vertical 69.564 Hz */ - 12, 0, 0, /* pixel 100.226 MHz */ - }, - { 1152, 900, 66, - 32, 208, 384, /* horizontal 61.817 KHz */ - 1, 32, 38, /* vertical 65.903 Hz */ - 124, 17, 0, /* pixel 94.951 MHz */ - }, - { 1280, 1024, 85, - 32, 248, 416, /* horizontal 90.561 KHz */ - 1, 40, 45, /* vertical 84.717 Hz */ - 116, 9, 0, /* pixel 153.593 MHz */ - }, - { 1280, 1024, 75, - 16, 248, 408, /* horizontal 80.255 KHz */ - 1, 38, 42, /* vertical 75.285 Hz */ - 111, 4, 1, /* pixel 134.828 MHz */ - }, - { 1280, 1024, 70, - 32, 248, 400, /* horizontal 74.573 KHz */ - 0, 36, 39, /* vertical 70.153 Hz */ - 68, 2, 1, /* pixel 125.283 MHz */ - }, - { 1280, 1024, 66, - 32, 248, 400, /* horizontal 70.007 KHz */ - 0, 36, 39, /* vertical 65.858 Hz */ - 113, 5, 1, /* pixel 117.612 MHz */ - }, - { 1280, 1024, 60, - 56, 240, 408, /* horizontal 70.007 KHz */ - 1, 38, 42, /* vertical 65.858 Hz */ - 113, 5, 1, /* pixel 117.612 MHz */ - }, - { 1600, 1200, 85, - 64, 304, 560, /* horizontal 106.059 KHz */ - 1, 46, 50, /* vertical 84.847 Hz */ - 126, 6, 0, /* pixel 229.088 MHz */ - }, - { 1600, 1200, 75, - 64, 304, 560, /* horizontal 93.748 KHz */ - 1, 46, 50, /* vertical 74.999 Hz */ - 97, 5, 0, /* pixel 202.497 MHz */ - }, - { 1600, 1200, 70, - 56, 304, 588, /* horizontal 87.524 KHz */ - 1, 46, 50, /* vertical 70.019 Hz */ - 105, 6, 0, /* pixel 191.503 MHz */ - }, - { 1600, 1200, 65, - 56, 308, 524, /* horizontal 80.050 KHz */ - 1, 38, 42, /* vertical 64.453 Hz */ - 93, 6, 0, /* pixel 170.026 MHz */ - }, -}; - -#define NUM_S3_TIMINGS (sizeof (s3Timings) / sizeof (s3Timings[0])) - static void _s3SetBlank (S3Ptr s3, S3Vga *s3vga, Bool blank) { @@ -173,17 +38,6 @@ _s3SetBlank (S3Ptr s3, S3Vga *s3vga, Bool blank) s3SetImm(s3vga, s3_screen_off, blank ? 1 : 0); } -static void -_s3SetDepth (S3Ptr s3, S3Vga *s3vga) -{ - CARD8 save_3c2; - _s3SetBlank (s3, s3vga, TRUE); - VgaFlush(&s3vga->card); - VgaSetImm (&s3vga->card, s3_clock_load_imm, 1); - VgaSetImm(&s3vga->card, s3_clock_load_imm, 0); - _s3SetBlank (s3, s3vga, FALSE); -} - Bool s3CardInit (KdCardInfo *card) { @@ -199,6 +53,7 @@ s3CardInit (KdCardInfo *card) VGA32 save_linear_window_size; VGA32 save_enable_linear; VGA32 save_register_lock_2; + VGA32 save_misc_output; s3c = (S3CardInfo *) xalloc (sizeof (S3CardInfo)); if (!s3c) @@ -210,7 +65,13 @@ s3CardInit (KdCardInfo *card) card->driver = s3c; - if (card->attr.naddr > 1) +#ifdef VXWORKS + s3c->bios_initialized = 0; +#else + s3c->bios_initialized = 1; +#endif + + if (card->attr.naddr > 1 && card->attr.address[1]) { s3FrameBuffer = card->attr.address[1]; s3Registers = card->attr.address[0]; @@ -240,6 +101,21 @@ s3CardInit (KdCardInfo *card) s3vga = &s3c->s3vga; s3RegInit (s3vga, (VGAVOL8 *) (registers + IOMAP_OFFSET)); + if (!s3c->bios_initialized) + { + volatile CARD32 *wakeup; + + wakeup = (volatile CARD32 *) (registers + 0x8510); + ErrorF ("Wakeup S3 chip at 0x%x\n", wakeup); + ErrorF ("Wakeup was 0x%x\n", *wakeup); + /* wakeup the chip */ + *(volatile CARD32 *) (registers + 0x8510) = 1; + ErrorF ("Wakeup is 0x%x\n", *wakeup); + } + s3Set (s3vga, s3_io_addr_select, 1); + s3Set (s3vga, s3_enable_ram, 1); + VgaFlush (&s3vga->card); + save_register_lock_2 = s3Get (s3vga, s3_register_lock_2); s3SetImm (s3vga, s3_register_lock_2, 0xa0); save_linear_window_size = s3Get (s3vga, s3_linear_window_size); @@ -292,20 +168,71 @@ bail0: } Bool +s3ModeSupported (KdScreenInfo *screen, + const KdMonitorTiming *t) +{ + /* make sure the clock isn't too fast */ + if (t->clock > S3_MAX_CLOCK * 2) + return FALSE; + /* width must be a multiple of 16 */ + if (t->horizontal & 0xf) + return FALSE; + return TRUE; +} + +Bool +s3ModeUsable (KdScreenInfo *screen) +{ + KdCardInfo *card = screen->card; + S3CardInfo *s3c = (S3CardInfo *) card->driver; + int screen_size; + int pixel_width; + int byte_width; + + if (screen->depth >= 24) + { + screen->depth = 24; + screen->bitsPerPixel = 32; + } + else if (screen->depth >= 16) + { + screen->depth = 16; + screen->bitsPerPixel = 16; + } + else if (screen->depth >= 15) + { + screen->depth = 15; + screen->bitsPerPixel = 16; + } + else + { + screen->depth = 8; + screen->bitsPerPixel = 8; + } + + byte_width = screen->width * (screen->bitsPerPixel >> 3); + pixel_width = screen->width; + screen->pixelStride = pixel_width; + screen->byteStride = byte_width; + + screen_size = byte_width * screen->height; + + return screen_size <= s3c->memory; +} + +Bool s3ScreenInit (KdScreenInfo *screen) { KdCardInfo *card = screen->card; S3CardInfo *s3c = (S3CardInfo *) card->driver; S3ScreenInfo *s3s; - int screen_size; int memory; int requested_memory; int v_total, h_total; - int byte_width; - int pixel_width; int m, n, r; int i; - S3Timing *t; + const KdMonitorTiming *t; + int screen_size; s3s = (S3ScreenInfo *) xalloc (sizeof (S3ScreenInfo)); if (!s3s) @@ -313,6 +240,12 @@ s3ScreenInit (KdScreenInfo *screen) memset (s3s, '\0', sizeof (S3ScreenInfo)); +#ifdef PHOENIX + screen->width = 1152; + screen->height = 900; + screen->rate = 85; + screen->depth = 32; +#endif if (!screen->width || !screen->height) { screen->width = 800; @@ -322,113 +255,29 @@ s3ScreenInit (KdScreenInfo *screen) if (!screen->depth) screen->depth = 8; - for (i = 0, t = s3Timings; i < NUM_S3_TIMINGS; i++, t++) - { - if (t->horizontal >= screen->width && - t->vertical >= screen->height && - (!screen->rate || t->rate <= screen->rate)) - break; - } - if (i == NUM_S3_TIMINGS) - t = &s3Timings[DEFAULT_S3_TIMING]; + t = KdFindMode (screen, s3ModeSupported); screen->rate = t->rate; screen->width = t->horizontal; screen->height = t->vertical; - s3GetClock (S3ModeClock(t), &m, &n, &r, 511, 127, 4); + s3GetClock (t->clock, &m, &n, &r, 511, 127, 4); #ifdef DEBUG - fprintf (stderr, "computed %d,%d,%d (%d) provided %d,%d,%d (%d)\n", - m, n, r, S3_CLOCK(m,n,r), - t->dac_m, t->dac_n, t->dac_r, - S3_CLOCK(t->dac_m, t->dac_n, t->dac_r)); + fprintf (stderr, "computed %d,%d,%d (%d)\n", + m, n, r, S3_CLOCK(m,n,r)); #endif /* - * Can only operate in pixel-doubled mode at 8 bits per pixel + * Can only operate in pixel-doubled mode at 8 or 16 bits per pixel */ if (screen->depth > 16 && S3_CLOCK(m,n,r) > S3_MAX_CLOCK) screen->depth = 16; - for (;;) + if (!KdTuneMode (screen, s3ModeUsable, s3ModeSupported)) { - if (screen->depth >= 24) - { - screen->depth = 24; - screen->bitsPerPixel = 32; - } - else if (screen->depth >= 16) - { - screen->depth = 16; - screen->bitsPerPixel = 16; - } - else if (screen->depth >= 15) - { - screen->depth = 15; - screen->bitsPerPixel = 16; - } - else - { - screen->depth = 8; - screen->bitsPerPixel = 8; - } - - /* Normalize width to supported values */ - - if (screen->width >= 1600) - screen->width = 1600; - else if (screen->width >= 1280) - screen->width = 1280; - else if (screen->width >= 1152) - screen->width = 1152; - else if (screen->width >= 1024) - screen->width = 1024; - else if (screen->width >= 800) - screen->width = 800; - else - screen->width = 640; - - byte_width = screen->width * (screen->bitsPerPixel >> 3); - pixel_width = screen->width; - screen->pixelStride = pixel_width; - screen->byteStride = byte_width; - - screen_size = byte_width * screen->height; - - if (screen_size <= s3c->memory) - break; - - /* - * Fix requested depth and geometry until it works - */ - if (screen->depth > 16) - screen->depth = 16; - else if (screen->depth > 8) - screen->depth = 8; - else if (screen->width > 1152) - { - screen->width = 1152; - screen->height = 900; - } - else if (screen->width > 1024) - { - screen->width = 1024; - screen->height = 768; - } - else if (screen->width > 800) - { - screen->width = 800; - screen->height = 600; - } - else if (screen->width > 640) - { - screen->width = 640; - screen->height = 480; - } - else - { - xfree (s3s); - return FALSE; - } + xfree (s3s); + return FALSE; } + screen_size = screen->byteStride * screen->height; + memory = s3c->memory - screen_size; /* @@ -451,21 +300,21 @@ s3ScreenInit (KdScreenInfo *screen) * Use remaining memory for off-screen storage, but only use * one piece (either right or bottom). */ - if (memory >= byte_width * S3_TILE_SIZE) + if (memory >= screen->byteStride * S3_TILE_SIZE) { s3s->offscreen = s3c->frameBuffer + screen_size; s3s->offscreen_x = 0; - s3s->offscreen_y = screen_size / byte_width; - s3s->offscreen_width = pixel_width; - s3s->offscreen_height = memory / byte_width; - memory -= s3s->offscreen_height * byte_width; + s3s->offscreen_y = screen_size / screen->byteStride; + s3s->offscreen_width = screen->pixelStride; + s3s->offscreen_height = memory / screen->byteStride; + memory -= s3s->offscreen_height * screen->byteStride; } - else if (pixel_width - screen->width >= S3_TILE_SIZE) + else if (screen->pixelStride - screen->width >= S3_TILE_SIZE) { s3s->offscreen = s3c->frameBuffer + screen->width; s3s->offscreen_x = screen->width; s3s->offscreen_y = 0; - s3s->offscreen_width = pixel_width - screen->width; + s3s->offscreen_width = screen->pixelStride - screen->width; s3s->offscreen_height = screen->height; } else @@ -508,6 +357,461 @@ s3ScreenInit (KdScreenInfo *screen) return TRUE; } +typedef struct _biosInit { + VGA16 reg; + VGA8 value; +} s3BiosInit; + +s3BiosInit s3BiosReg[] = { + S3_SR +0x15, 0x23, + S3_MISC_OUT, 0x2f, + 0xffff, 1, + S3_SR +0x15, 0x03, + + S3_SR + 0x0, 0x03, + S3_SR + 0x1, 0x00, + S3_SR + 0x2, 0x03, + S3_SR + 0x3, 0x00, + S3_SR + 0x4, 0x02, + S3_SR + 0x5, 0x05, + S3_SR + 0x6, 0x06, + S3_SR + 0x7, 0x07, +/* S3_SR + 0x8, 0x06, */ + S3_SR + 0x9, 0x00, + S3_SR + 0xa, 0x0a, + S3_SR + 0xb, 0x00, + S3_SR + 0xc, 0x0c, + S3_SR + 0xd, 0x00, + S3_SR + 0xe, 0x0e, + S3_SR + 0xf, 0x0f, + +/* S3_SR +0x10, 0x00, */ +/* S3_SR +0x11, 0x0c, */ + S3_SR +0x12, 0x01, + S3_SR +0x13, 0x52, + S3_SR +0x14, 0x00, + +/* S3_SR +0x15, 0x03, */ + + S3_SR +0x16, 0xc5, + S3_SR +0x17, 0xfc, + S3_SR +0x18, 0x40, + S3_SR +0x19, 0x00, + S3_SR +0x1a, 0x01, + S3_SR +0x1b, 0x02, + S3_SR +0x1c, 0x5d, + S3_SR +0x1d, 0x00, + S3_SR +0x1e, 0x00, + S3_SR +0x1f, 0x00, + S3_SR +0x20, 0x20, + S3_SR +0x21, 0x21, + S3_SR +0x22, 0x22, + S3_SR +0x23, 0x23, + S3_SR +0x24, 0x24, + S3_SR +0x25, 0x25, + S3_SR +0x26, 0x26, + S3_SR +0x27, 0x04, + S3_SR +0x28, 0xff, + S3_SR +0x29, 0x00, + S3_SR +0x2a, 0x2a, + S3_SR +0x2b, 0x2b, + S3_SR +0x2c, 0x2c, + S3_SR +0x2d, 0x2d, + S3_SR +0x2e, 0x2e, + S3_SR +0x2f, 0x2f, + S3_SR +0x30, 0x00, + S3_SR +0x31, 0x06, + S3_SR +0x32, 0x41, + S3_SR +0x33, 0x67, + S3_SR +0x34, 0x00, + S3_SR +0x35, 0x00, + S3_SR +0x36, 0x01, + S3_SR +0x37, 0x52, + S3_SR +0x38, 0x5d, + S3_SR +0x39, 0x05, + S3_SR +0x3a, 0x3a, + S3_SR +0x3b, 0x3b, + S3_SR +0x3c, 0x3c, + S3_SR +0x3d, 0x00, + S3_SR +0x3e, 0x3e, + S3_SR +0x3f, 0x00, + S3_SR +0x40, 0x40, + S3_SR +0x41, 0x41, + S3_SR +0x42, 0x42, + S3_SR +0x43, 0x43, + S3_SR +0x44, 0x44, + S3_SR +0x45, 0x45, + S3_SR +0x46, 0x46, + S3_SR +0x47, 0x47, + S3_SR +0x48, 0x48, + S3_SR +0x49, 0x49, + S3_SR +0x4a, 0x4a, + S3_SR +0x4b, 0x4b, + S3_SR +0x4c, 0x4c, + S3_SR +0x4d, 0x4d, + S3_SR +0x4e, 0x4e, + S3_SR +0x4f, 0x4f, + S3_SR +0x50, 0x00, + S3_SR +0x51, 0x00, + S3_SR +0x52, 0x00, + S3_SR +0x53, 0x00, + S3_SR +0x54, 0x00, + S3_SR +0x55, 0x00, + S3_SR +0x56, 0x00, + S3_SR +0x57, 0x00, + S3_SR +0x58, 0x00, + S3_SR +0x59, 0x70, + S3_SR +0x5a, 0x38, + S3_SR +0x5b, 0x08, + S3_SR +0x5c, 0x77, + S3_SR +0x5d, 0x77, + S3_SR +0x5e, 0x00, + S3_SR +0x5f, 0x00, + S3_SR +0x60, 0xff, + S3_SR +0x61, 0xbf, + S3_SR +0x62, 0xff, + S3_SR +0x63, 0xff, + S3_SR +0x64, 0xf7, + S3_SR +0x65, 0xff, + S3_SR +0x66, 0xff, + S3_SR +0x67, 0xff, + S3_SR +0x68, 0xff, + S3_SR +0x69, 0xff, + S3_SR +0x6a, 0xff, + S3_SR +0x6b, 0xff, + S3_SR +0x6c, 0xff, + S3_SR +0x6d, 0xff, + S3_SR +0x6e, 0x9b, + S3_SR +0x6f, 0xbf, + + S3_AR + 0x00, 0x00, + S3_AR + 0x01, 0x01, + S3_AR + 0x02, 0x02, + S3_AR + 0x03, 0x03, + S3_AR + 0x04, 0x04, + S3_AR + 0x05, 0x05, + S3_AR + 0x06, 0x06, + S3_AR + 0x07, 0x07, + S3_AR + 0x08, 0x08, + S3_AR + 0x09, 0x09, + S3_AR + 0x0a, 0x0a, + S3_AR + 0x0b, 0x0b, + S3_AR + 0x0c, 0x0c, + S3_AR + 0x0d, 0x0d, + S3_AR + 0x0e, 0x0e, + S3_AR + 0x0f, 0x0f, + S3_AR + 0x10, 0x05, + S3_AR + 0x11, 0x00, + S3_AR + 0x12, 0x0f, + S3_AR + 0x13, 0x08, + S3_AR + 0x14, 0x00, + + S3_GR + 0x00, 0x00, + S3_GR + 0x01, 0x00, + S3_GR + 0x02, 0x00, + S3_GR + 0x03, 0x00, + S3_GR + 0x04, 0x00, + S3_GR + 0x05, 0x10, + S3_GR + 0x06, 0x0e, + S3_GR + 0x07, 0x00, + + S3_CR + 0x00, 0x5f, + S3_CR + 0x01, 0x4f, + S3_CR + 0x02, 0x50, + S3_CR + 0x03, 0x82, + S3_CR + 0x04, 0x55, + S3_CR + 0x05, 0x81, + S3_CR + 0x06, 0xbf, + S3_CR + 0x07, 0x1f, + S3_CR + 0x08, 0x00, + S3_CR + 0x09, 0x4f, + S3_CR + 0x0a, 0x0d, + S3_CR + 0x0b, 0x0e, + S3_CR + 0x0c, 0x00, + S3_CR + 0x0d, 0x00, + S3_CR + 0x0e, 0x3f, + S3_CR + 0x0f, 0xff, + S3_CR + 0x10, 0x9c, + S3_CR + 0x11, 0x0e, + S3_CR + 0x12, 0x8f, + S3_CR + 0x13, 0x28, + S3_CR + 0x14, 0x1f, + S3_CR + 0x15, 0x96, + S3_CR + 0x16, 0xb9, + S3_CR + 0x17, 0xa3, + S3_CR + 0x18, 0xff, + S3_CR + 0x19, 0xdf, + S3_CR + 0x1a, 0xdf, + S3_CR + 0x1b, 0xdf, + S3_CR + 0x1c, 0xdf, + S3_CR + 0x1d, 0xdf, + S3_CR + 0x1e, 0xdf, + S3_CR + 0x1f, 0xdf, + S3_CR + 0x20, 0xdf, + S3_CR + 0x21, 0x00, +/* S3_CR + 0x22, 0x07, */ + S3_CR + 0x23, 0x00, + S3_CR + 0x24, 0xdf, + S3_CR + 0x25, 0xdf, + S3_CR + 0x26, 0x00, + S3_CR + 0x27, 0xdf, + S3_CR + 0x28, 0xdf, + S3_CR + 0x29, 0xdf, + S3_CR + 0x2a, 0xdf, + S3_CR + 0x2b, 0xdf, + S3_CR + 0x2c, 0xdf, + S3_CR + 0x2d, 0x8a, + S3_CR + 0x2e, 0x22, + S3_CR + 0x2f, 0x02, + S3_CR + 0x30, 0xe1, + S3_CR + 0x31, 0x05, + S3_CR + 0x32, 0x40, + S3_CR + 0x33, 0x08, + S3_CR + 0x34, 0x00, + S3_CR + 0x35, 0x00, + S3_CR + 0x36, 0xbf, + S3_CR + 0x37, 0x9b, +/* S3_CR + 0x38, 0x7b, */ +/* S3_CR + 0x39, 0xb8, */ + S3_CR + 0x3a, 0x45, + S3_CR + 0x3b, 0x5a, + S3_CR + 0x3c, 0x10, + S3_CR + 0x3d, 0x00, + S3_CR + 0x3e, 0xfd, + S3_CR + 0x3f, 0x00, + S3_CR + 0x40, 0x00, + S3_CR + 0x41, 0x92, + S3_CR + 0x42, 0xc0, + S3_CR + 0x43, 0x68, + S3_CR + 0x44, 0xff, + S3_CR + 0x45, 0xe8, + S3_CR + 0x46, 0xff, + S3_CR + 0x47, 0xff, + S3_CR + 0x48, 0xf8, + S3_CR + 0x49, 0xff, + S3_CR + 0x4a, 0xfe, + S3_CR + 0x4b, 0xff, + S3_CR + 0x4c, 0xff, + S3_CR + 0x4d, 0xff, + S3_CR + 0x4e, 0xff, + S3_CR + 0x4f, 0xff, + S3_CR + 0x50, 0x00, + S3_CR + 0x51, 0x00, + S3_CR + 0x52, 0x00, + S3_CR + 0x53, 0x00, + S3_CR + 0x54, 0x00, + S3_CR + 0x55, 0x00, + S3_CR + 0x56, 0x00, + S3_CR + 0x57, 0x00, +#if 0 + S3_CR + 0x58, 0x00, + S3_CR + 0x59, 0xf0, +#endif + S3_CR + 0x5a, 0x00, + S3_CR + 0x5b, 0x00, +#if 0 + S3_CR + 0x5c, 0x00, +#endif + S3_CR + 0x5d, 0x00, + S3_CR + 0x5e, 0x00, + S3_CR + 0x5f, 0x00, + S3_CR + 0x60, 0x09, + S3_CR + 0x61, 0x9d, + S3_CR + 0x62, 0xff, + S3_CR + 0x63, 0x00, + S3_CR + 0x64, 0xfd, + S3_CR + 0x65, 0x04, + S3_CR + 0x66, 0x88, + S3_CR + 0x67, 0x00, + S3_CR + 0x68, 0x7f, + S3_CR + 0x69, 0x00, + S3_CR + 0x6a, 0x00, + S3_CR + 0x6b, 0x00, + S3_CR + 0x6c, 0x00, + S3_CR + 0x6d, 0x11, + S3_CR + 0x6e, 0xff, + S3_CR + 0x6f, 0xfe, + + S3_CR + 0x70, 0x30, + S3_CR + 0x71, 0xc0, + S3_CR + 0x72, 0x07, + S3_CR + 0x73, 0x1f, + S3_CR + 0x74, 0x1f, + S3_CR + 0x75, 0x1f, + S3_CR + 0x76, 0x0f, + S3_CR + 0x77, 0x1f, + S3_CR + 0x78, 0x01, + S3_CR + 0x79, 0x01, + S3_CR + 0x7a, 0x1f, + S3_CR + 0x7b, 0x1f, + S3_CR + 0x7c, 0x17, + S3_CR + 0x7d, 0x17, + S3_CR + 0x7e, 0x17, + S3_CR + 0x7f, 0xfd, + S3_CR + 0x80, 0x00, + S3_CR + 0x81, 0x92, + S3_CR + 0x82, 0x10, + S3_CR + 0x83, 0x07, + S3_CR + 0x84, 0x42, + S3_CR + 0x85, 0x00, + S3_CR + 0x86, 0x00, + S3_CR + 0x87, 0x00, + S3_CR + 0x88, 0x10, + S3_CR + 0x89, 0xfd, + S3_CR + 0x8a, 0xfd, + S3_CR + 0x8b, 0xfd, + S3_CR + 0x8c, 0xfd, + S3_CR + 0x8d, 0xfd, + S3_CR + 0x8e, 0xfd, + S3_CR + 0x8f, 0xfd, + S3_CR + 0x90, 0x00, + S3_CR + 0x91, 0x4f, + S3_CR + 0x92, 0x10, + S3_CR + 0x93, 0x00, + S3_CR + 0x94, 0xfd, + S3_CR + 0x95, 0xfd, + S3_CR + 0x96, 0xfd, + S3_CR + 0x97, 0xfd, + S3_CR + 0x98, 0xfd, + S3_CR + 0x99, 0xff, + S3_CR + 0x9a, 0xfd, + S3_CR + 0x9b, 0xff, + S3_CR + 0x9c, 0xfd, + S3_CR + 0x9d, 0xfd, + S3_CR + 0x9e, 0xfd, + S3_CR + 0x9f, 0xff, + S3_CR + 0xa0, 0x0f, +#if 0 + S3_CR + 0xa1, 0x00, + S3_CR + 0xa2, 0x00, + S3_CR + 0xa3, 0x00, + S3_CR + 0xa4, 0x55, +#endif + S3_CR + 0xa5, 0x09, + S3_CR + 0xa6, 0x20, +#if 0 + S3_CR + 0xa7, 0x00, + S3_CR + 0xa8, 0x00, + S3_CR + 0xa9, 0x00, + S3_CR + 0xaa, 0x00, + S3_CR + 0xab, 0x00, + S3_CR + 0xac, 0x00, + S3_CR + 0xad, 0x00, + S3_CR + 0xae, 0x00, + S3_CR + 0xaf, 0x00, + S3_CR + 0xb0, 0xff, +#endif + S3_CR + 0xb1, 0x0e, +#if 0 + S3_CR + 0xb2, 0x55, + S3_CR + 0xb3, 0x00, + S3_CR + 0xb4, 0x55, + S3_CR + 0xb5, 0x00, + S3_CR + 0xb6, 0x00, +#endif + S3_CR + 0xb7, 0x84, +#if 0 + S3_CR + 0xb8, 0xff, + S3_CR + 0xb9, 0xff, + S3_CR + 0xba, 0xff, + S3_CR + 0xbb, 0xff, + S3_CR + 0xbc, 0xff, + S3_CR + 0xbd, 0xff, + S3_CR + 0xbe, 0xff, + S3_CR + 0xbf, 0xff, +#endif + + S3_SR +0x15, 0x23, + 0xffff, 1, + S3_SR +0x15, 0x03, + 0xffff, 1, +}; + +#define S3_NUM_BIOS_REG (sizeof (s3BiosReg) / sizeof (s3BiosReg[0])) + +typedef struct _bios32Init { + VGA16 offset; + VGA32 value; +} s3Bios32Init; + +s3Bios32Init s3Bios32Reg[] = { + 0x8168, 0x00000000, + 0x816c, 0x00000001, + 0x8170, 0x00000000, + 0x8174, 0x00000000, + 0x8178, 0x00000000, + 0x817c, 0x00000000, +#if 0 + 0x8180, 0x00140000, + 0x8184, 0x00000000, + 0x8188, 0x00000000, + 0x8190, 0x00000000, + 0x8194, 0x00000000, + 0x8198, 0x00000000, + 0x819c, 0x00000000, + 0x81a0, 0x00000000, +#endif + 0x81c0, 0x00000000, + 0x81c4, 0x01fbffff, + 0x81c8, 0x00f7ffbf, + 0x81cc, 0x00f7ff00, + 0x81d0, 0x11ffff7f, + 0x81d4, 0x7fffffdf, + 0x81d8, 0xfdfff9ff, + 0x81e0, 0xfd000000, + 0x81e4, 0x00000000, + 0x81e8, 0x00000000, + 0x81ec, 0x00010000, + 0x81f0, 0x07ff057f, + 0x81f4, 0x07ff07ff, + 0x81f8, 0x00000000, + 0x81fc, 0x00000000, + 0x8200, 0x00000000, + 0x8204, 0x00000000, + 0x8208, 0x33000000, + 0x820c, 0x7f000000, + 0x8210, 0x80000000, + 0x8214, 0x00000000, + 0x8218, 0xffffffff, + 0x8300, 0xff007fef, + 0x8304, 0xfffdf7bf, + 0x8308, 0xfdfffbff, +}; + +#define S3_NUM_BIOS32_REG (sizeof (s3Bios32Reg) / sizeof (s3Bios32Reg[0])) + +/* + * Initialize the card precisely as the bios does + */ +s3DoBiosInit (KdCardInfo *card) +{ + S3CardInfo *s3c = card->driver; + CARD32 *regs = (CARD32 *) s3c->registers; + S3Vga *s3vga = &s3c->s3vga; + int r; + + for (r = 0; r < S3_NUM_BIOS_REG; r++) + { + if (s3BiosReg[r].reg == 0xffff) + sleep (s3BiosReg[r].value); + else + VgaStore (&s3vga->card, s3BiosReg[r].reg, s3BiosReg[r].value); + } + VgaStore (&s3vga->card, S3_SR+0x10, 0x22); + VgaStore (&s3vga->card, S3_SR+0x11, 0x44); + VgaStore (&s3vga->card, S3_SR+0x15, 0x01); + sleep (1); + VgaStore (&s3vga->card, S3_SR+0x15, 0x03); + VgaStore (&s3vga->card, S3_CR+0x6f, 0xff); + VgaStore (&s3vga->card, S3_CR+0x3f, 0x3f); + sleep (1); + VgaStore (&s3vga->card, S3_CR+0x3f, 0x00); + VgaStore (&s3vga->card, S3_CR+0x6f, 0xfe); + VgaInvalidate (&s3vga->card); + for (r = 0; r < S3_NUM_BIOS32_REG; r++) + regs[s3Bios32Reg[r].offset/4] = s3Bios32Reg[r].value; +} + void s3Preserve (KdCardInfo *card) { @@ -519,6 +823,9 @@ s3Preserve (KdCardInfo *card) CARD8 *cursor_base; s3Save (s3vga); + if (!s3c->bios_initialized) + s3DoBiosInit (card); + _s3SetBlank (s3, s3vga, TRUE); /* * Preserve the first part of the frame buffer which holds @@ -535,6 +842,9 @@ s3Preserve (KdCardInfo *card) save->write_mask = s3->write_mask; save->fg = s3->fg; save->bg = s3->bg; + save->global_bitmap_1 = s3->global_bitmap_1; + save->global_bitmap_2 = s3->global_bitmap_2; + save->primary_bitmap_1 = s3->primary_bitmap_1; _s3SetBlank (s3, s3vga, FALSE); } @@ -542,6 +852,8 @@ s3Preserve (KdCardInfo *card) * Enable the card for rendering. Manipulate the initial settings * of the card here. */ +int s3CpuTimeout, s3AccelTimeout; + void s3Enable (ScreenPtr pScreen) { @@ -552,6 +864,7 @@ s3Enable (ScreenPtr pScreen) s3ScreenInfo (pScreenPriv); S3Vga *s3vga = &s3c->s3vga; + S3Ptr s3 = s3c->s3; int hactive, hblank, hfp, hbp; int vactive, vblank, vfp, vbp; int hsize; @@ -580,21 +893,14 @@ s3Enable (ScreenPtr pScreen) int h_blank_extend; int i; CARD16 cursor_address; - S3Timing *t; + const KdMonitorTiming *t; int m, n, r; Bool clock_double; + int cpu_timeout; + int accel_timeout; + int bytes_per_ms; - for (i = 0; i < NUM_S3_TIMINGS; i++) - { - t = &s3Timings[i]; - - if (t->horizontal == screen->width && - t->vertical == screen->height && - t->rate <= screen->rate) - break; - } - if (i == NUM_S3_TIMINGS) - t = &s3Timings[DEFAULT_S3_TIMING]; + t = KdFindMode (screen, s3ModeSupported); hfp = t->hfp; hbp = t->hbp; @@ -613,7 +919,7 @@ s3Enable (ScreenPtr pScreen) fprintf (stderr, "old clock %d, %d, %d\n", m, n, r); #endif clock_double = FALSE; - s3GetClock (S3ModeClock(t), &m, &n, &r, 511, 127, 4); + s3GetClock (t->clock, &m, &n, &r, 511, 127, 4); if (S3_CLOCK(m,n,r) > S3_MAX_CLOCK) clock_double = TRUE; s3Set (s3vga, s3_clock_select, 3); @@ -621,7 +927,7 @@ s3Enable (ScreenPtr pScreen) s3Set (s3vga, s3_dclk_n, n); s3Set (s3vga, s3_dclk_r, r); #ifdef DEBUG - fprintf (stderr, "new clock %d, %d, %d\n", m, n, r); + fprintf (stderr, "new clock %d, %d, %d (%d)\n", m, n, r, S3_CLOCK(m,n,r)); #endif s3Set (s3vga, s3_select_graphics_mode, 1); @@ -630,7 +936,13 @@ s3Enable (ScreenPtr pScreen) s3Set (s3vga, s3_enhanced_memory_mapping, 1); s3Set (s3vga, s3_enable_sff, 1); s3Set (s3vga, s3_enable_2d_access, 1); + s3Set (s3vga, s3_2bk_cga, 1); + s3Set (s3vga, s3_4bk_hga, 1); + s3Set (s3vga, s3_v_total_double, 0); + s3Set (s3vga, s3_address_16k_wrap, 1); + s3Set (s3vga, s3_word_mode, 0); s3Set (s3vga, s3_byte_mode, 1); + s3Set (s3vga, s3_hardware_reset, 1); s3Set (s3vga, s3_max_scan_line, 0); s3Set (s3vga, s3_linear_window_size, 3); s3Set (s3vga, s3_enable_linear, 1); @@ -639,31 +951,31 @@ s3Enable (ScreenPtr pScreen) s3Set (s3vga, s3_disable_pci_read_bursts, 0); s3Set (s3vga, s3_pci_retry_enable, 1); s3Set (s3vga, s3_enable_256, 1); -#if 1 - s3Set (s3vga, s3_border_select, 1); /* eliminate white border */ -#else +/* s3Set (s3vga, s3_border_select, 1); /* eliminate white border */ s3Set (s3vga, s3_border_select, 0); /* eliminate white border */ -#endif + s3SetImm (s3vga, s3_lock_palette, 0); /* unlock palette/border regs */ s3Set (s3vga, s3_disable_v_retrace_int, 1); - s3Set (s3vga, s3_horz_sync_neg, 0); - s3Set (s3vga, s3_vert_sync_neg, 0); + if (t->hpol == KdSyncPositive) + s3Set (s3vga, s3_horz_sync_neg, 0); + else + s3Set (s3vga, s3_horz_sync_neg, 1); + if (t->vpol == KdSyncPositive) + s3Set (s3vga, s3_vert_sync_neg, 0); + else + s3Set (s3vga, s3_vert_sync_neg, 1); s3Set (s3vga, s3_dot_clock_8, 1); s3Set (s3vga, s3_enable_write_plane, 0xf); s3Set (s3vga, s3_extended_memory_access, 1); s3Set (s3vga, s3_sequential_addressing_mode, 1); s3Set (s3vga, s3_select_chain_4_mode, 1); -#if 1 s3Set (s3vga, s3_linear_addressing_control, 1); -#else - s3Set (s3vga, s3_linear_addressing_control, 0); -#endif s3Set (s3vga, s3_enable_8_bit_luts, 1); s3Set (s3vga, s3_dclk_invert, 0); s3Set (s3vga, s3_enable_clock_double, 0); + s3Set (s3vga, s3_dclk_over_2, 0); - s3Set (s3vga, s3_cpu_timeout, 0x1f); s3Set (s3vga, s3_fifo_fetch_timing, 1); s3Set (s3vga, s3_fifo_drain_delay, 7); @@ -671,19 +983,27 @@ s3Enable (ScreenPtr pScreen) s3Set (s3vga, s3_delay_h_enable, 0); s3Set (s3vga, s3_sdclk_skew, 0); + s3Set (s3vga, s3_dac_mask, 0xff); + + s3Set (s3vga, s3_dac_power_saving_disable, 1); + + s3s->manage_border = FALSE; /* * Compute character lengths for horizontal timing values */ + hactive = screen->width / 8; + hblank /= 8; + hfp /= 8; + hbp /= 8; + /* + * Set pixel size, choose clock doubling mode + */ h_blank_start_adjust = 0; h_blank_end_adjust = 0; + switch (screen->bitsPerPixel) { case 8: - hactive = screen->width / 8; - hblank /= 8; - hfp /= 8; - hbp /= 8; h_screen_off = hactive; - s3Set (s3vga, s3_2d_graphics_engine_timeout, 0x1f); s3Set (s3vga, s3_pixel_length, 0); s3Set (s3vga, s3_color_mode, 0); /* @@ -696,23 +1016,15 @@ s3Enable (ScreenPtr pScreen) s3Set (s3vga, s3_dclk_over_2, 1); s3Set (s3vga, s3_enable_clock_double, 1); s3Set (s3vga, s3_border_select, 0); -#if 0 - s3Set (s3vga, s3_delay_blank, 2); - s3Set (s3vga, s3_delay_h_enable, 2); - crtc->extended_bios_5 = 2; -#endif - h_blank_start_adjust = -1; - h_blank_end_adjust = 0; +/* s3Set (s3vga, s3_border_color, pScreen->blackPixel); */ + h_blank_start_adjust = 4; + h_blank_end_adjust = -4; + s3s->manage_border = TRUE; } break; case 16: - hactive = screen->width / 8; - hblank /= 8; - hfp /= 8; - hbp /= 8; h_screen_off = hactive * 2; s3Set (s3vga, s3_pixel_length, 1); - s3Set (s3vga, s3_2d_graphics_engine_timeout, 0x14); if (clock_double) { if (screen->depth == 15) @@ -722,6 +1034,8 @@ s3Enable (ScreenPtr pScreen) s3Set (s3vga, s3_dclk_over_2, 1); s3Set (s3vga, s3_enable_clock_double, 1); s3Set (s3vga, s3_border_select, 0); + h_blank_start_adjust = 4; + h_blank_end_adjust = -4; } else { @@ -735,14 +1049,9 @@ s3Enable (ScreenPtr pScreen) } break; case 32: - hactive = screen->width / 8; - hblank /= 8; - hfp /= 8; - hbp /= 8; h_screen_off = hactive * 4; s3Set (s3vga, s3_pixel_length, 3); s3Set (s3vga, s3_color_mode, 0xd); - s3Set (s3vga, s3_2d_graphics_engine_timeout, 0x07); break; } @@ -751,6 +1060,57 @@ s3Enable (ScreenPtr pScreen) */ s3Set (s3vga, s3_start_address, 0); + + /* + * Set various registers to avoid snow on the screen + */ + bytes_per_ms = t->clock * (screen->bitsPerPixel / 8); + + fprintf (stderr, "bytes_per_ms %d\n", bytes_per_ms); + fprintf (stderr, "primary 0x%x master 0x%x command 0x%x lpb 0x%x cpu 0x%x 2d 0x%x\n", + s3Get (s3vga, s3_primary_stream_timeout), + s3Get (s3vga, s3_master_control_unit_timeout), + s3Get (s3vga, s3_command_buffer_timeout), + s3Get (s3vga, s3_lpb_timeout), + s3Get (s3vga, s3_cpu_timeout), + s3Get (s3vga, s3_2d_graphics_engine_timeout)); + + /* cpu 2d + * 576000 + * 288000 0x1f 0x19 + + */ + if (s3CpuTimeout) + { + cpu_timeout = s3CpuTimeout; + if (s3AccelTimeout) + accel_timeout = s3AccelTimeout; + else + accel_timeout = s3CpuTimeout; + } + else if (bytes_per_ms > 400000) + { + cpu_timeout = 0x10; + accel_timeout = 0x7; + } + else if (bytes_per_ms > 250000) + { + cpu_timeout = 0x10; + accel_timeout = 0x18; + } + else + { + cpu_timeout = 0x1f; + accel_timeout = 0x1f; + } + + s3Set (s3vga, s3_primary_stream_timeout, 0xc0); + s3Set (s3vga, s3_master_control_unit_timeout, 0xf); + s3Set (s3vga, s3_command_buffer_timeout, 0x1f); + s3Set (s3vga, s3_lpb_timeout, 0xf); + s3Set (s3vga, s3_2d_graphics_engine_timeout, accel_timeout); + s3Set (s3vga, s3_cpu_timeout, cpu_timeout); + /* * Compute horizontal register values from timings */ @@ -855,6 +1215,12 @@ s3Enable (ScreenPtr pScreen) else s3Set (s3vga, s3_cursor_enable, 0); +#define MAKE_GBF(bds,be,stride,bpp,tile) (\ + ((bds) << 0) | \ + ((be) << 3) | \ + ((stride) << 4) | \ + ((bpp) << 16) | \ + ((tile) << 24)) /* * Set accelerator */ @@ -865,6 +1231,8 @@ s3Enable (ScreenPtr pScreen) case 1152: s3Set (s3vga, s3_ge_screen_width, 4); break; case 1280: s3Set (s3vga, s3_ge_screen_width, 3); break; case 1600: s3Set (s3vga, s3_ge_screen_width, 6); break; + default: + s3Set (s3vga, s3_ge_screen_width, 7); /* use global bitmap descriptor */ } #if 0 @@ -877,7 +1245,100 @@ s3Enable (ScreenPtr pScreen) s3Set (s3vga, s3_hsync_control, 0); s3Set (s3vga, s3_vsync_control, 0); - _s3SetDepth (s3c->s3, s3vga); + _s3SetBlank (s3, s3vga, TRUE); + VgaFlush(&s3vga->card); + VgaSetImm (&s3vga->card, s3_clock_load_imm, 1); + VgaSetImm(&s3vga->card, s3_clock_load_imm, 0); + s3->global_bitmap_1 = 0; + s3->global_bitmap_2 = MAKE_GBF (1, /* 64 bit bitmap descriptor size */ + 0, /* disable BCI */ + pScreenPriv->screen->pixelStride >> 4, + pScreenPriv->screen->bitsPerPixel, + 0); /* tile format */ + _s3SetBlank (s3, s3vga, FALSE); +#if 1 + { + VGA16 r; + static CARD32 streams[][2] = { + /* PCI registers */ + 0x8000, 0x8024, + 0x802c, 0x8034, + 0x803c, 0x8040, +#if 0 + 0x8080, 0x808c, /* AGP */ +#endif + 0x80dc, 0x80e0, + + /* 2D registers */ + 0x8168, 0x8188, + 0x8190, 0x81a0, + 0x81c0, 0x81d8, + 0x81e0, 0x8218, + 0x8300, 0x8308, + 0x8504, 0x8510, + + /* LPB/VIP registers */ + 0xff00, 0xff18, + 0xff20, 0xff38, + 0xff40, 0xff40, + 0xff70, 0xff78, + 0xff8c, 0xffa0, + +#if 0 + /* 3D registers */ + 0x48508, 0x48508, + 0x48528, 0x48528, + 0x48548, 0x48548, + 0x48584, 0x485f0, +#endif + + /* motion compensation registers */ + 0x48900, 0x48924, +#if 0 + 0x48928, 0x48928, +#endif + + /* Mastered data transfer registers */ + 0x48a00, 0x48a1c, + + /* configuation/status registers */ + 0x48c00, 0x48c18, + 0x48c20, 0x48c24, + 0x48c40, 0x48c50, + 0x48c60, 0x48c64, + + 0, 0, + }; +#ifdef PHOENIX +#undef stderr +#define stderr stdout +#endif + CARD32 *regs = (CARD32 *) s3c->registers; + int i; + CARD32 reg; + + + for (r = S3_SR + 0; r < S3_SR + S3_NSR; r++) + fprintf (stderr, "SR%02x = %02x\n", r-S3_SR, VgaFetch (&s3vga->card, r)); + for (r = S3_GR + 0; r < S3_GR + S3_NGR; r++) + fprintf (stderr, "GR%02x = %02x\n", r-S3_GR, VgaFetch (&s3vga->card, r)); + for (r = S3_AR + 0; r < S3_AR + S3_NAR; r++) + fprintf (stderr, "AR%02x = %02x\n", r-S3_AR, VgaFetch (&s3vga->card, r)); + for (r = S3_CR + 0; r < S3_CR + S3_NCR; r++) + fprintf (stderr, "CR%02x = %02x\n", r-S3_CR, VgaFetch (&s3vga->card, r)); + for (r = S3_DAC + 0; r < S3_DAC + S3_NDAC; r++) + fprintf (stderr, "DAC%02x = %02x\n", r-S3_DAC, VgaFetch (&s3vga->card, r)); + fprintf (stderr, "MISC_OUT = %02x\n", VgaFetch (&s3vga->card, S3_MISC_OUT)); + fprintf (stderr, "INPUT_STATUS = %02x\n", VgaFetch (&s3vga->card, S3_INPUT_STATUS_1)); + + + for (i = 0; streams[i][0]; i++) + { + for (reg = streams[i][0]; reg <= streams[i][1]; reg += 4) + fprintf (stderr, "0x%4x: 0x%08x\n", reg, regs[reg/4]); + } + } +#endif } void @@ -895,6 +1356,8 @@ s3Restore (KdCardInfo *card) CARD8 *cursor_base; /* graphics engine state */ + s3->global_bitmap_1 = save->global_bitmap_1; + s3->global_bitmap_2 = save->global_bitmap_2; s3->alt_mix = save->alt_mix; s3->write_mask = save->write_mask; s3->fg = save->fg; @@ -976,6 +1439,7 @@ s3CardFini (KdCardInfo *card) KdCardFuncs s3Funcs = { s3CardInit, s3ScreenInit, + 0, s3Preserve, s3Enable, s3DPMS, @@ -990,6 +1454,7 @@ KdCardFuncs s3Funcs = { s3RecolorCursor, s3DrawInit, s3DrawEnable, + s3DrawSync, s3DrawDisable, s3DrawFini, s3GetColors, diff --git a/hw/kdrive/savage/s3.h b/hw/kdrive/savage/s3.h index 95a8edddd..2c07210b1 100644 --- a/hw/kdrive/savage/s3.h +++ b/hw/kdrive/savage/s3.h @@ -22,7 +22,7 @@ * * Author: Keith Packard, SuSE, Inc. */ -/* $XFree86: $ */ +/* $XFree86: xc/programs/Xserver/hw/kdrive/savage/s3.h,v 1.1 1999/11/19 13:53:55 hohndel Exp $ */ #ifndef _S3_H_ #define _S3_H_ @@ -30,8 +30,6 @@ #include "kdrive.h" #include "s3reg.h" -#define PLATFORM 300 - /* VESA Approved Register Definitions */ /* @@ -74,14 +72,42 @@ typedef volatile struct _s3 { VOL32 alt_mix; /* 8134 */ VOL32 scissors_tl; /* 8138 */ VOL32 scissors_br; /* 813c */ +#if 0 VOL16 pix_cntl; /* 8140 */ VOL16 mult_misc2; /* 8142 */ +#else + VOL32 pix_cntl_mult_misc2; /* 8140 */ +#endif VOL32 mult_misc_read_sel; /* 8144 */ VOL32 alt_pcnt; /* 8148 min_axis_pcnt, maj_axis_pcnt */ - VOL8 _pad3[0x19c]; /* 814c */ + VOL8 _pad3a[0x1c]; /* 814c */ + VOL32 global_bitmap_1; /* 8168 */ + VOL32 global_bitmap_2; /* 816c */ + VOL32 primary_bitmap_1; /* 8170 */ + VOL32 primary_bitmap_2; /* 8174 */ + VOL32 secondary_bitmap_1; /* 8178 */ + VOL32 secondary_bitmap_2; /* 817c */ + VOL32 primary_stream_control; /* 8180 */ + VOL32 chroma_key_control; /* 8184 */ + VOL32 genlocking_control; /* 8188 */ + VOL8 _pad3b[0x4]; /* 818c */ + VOL32 secondary_stream_control; /* 8190 */ + VOL32 chroma_key_upper_bound; /* 8194 */ + VOL32 secondary_stream_h_scale; /* 8198 */ + VOL32 color_adjustment; /* 819c */ + VOL32 blend_control; /* 81a0 */ + VOL8 _pad3c[0x1c]; /* 81a4 */ + VOL32 primary_stream_addr_0; /* 81c0 */ + VOL8 _pad3d[0x124]; /* 81c4 */ +#if 0 VOL16 cur_y; /* 82e8 */ VOL8 _pad4[0xc6]; /* 82ea */ +#else + VOL32 cur_y; /* 82e8 */ + VOL8 _pad4[0xc4]; /* 82ec */ +#endif +#if 0 VOL8 crt_vga_3b0; /* 83b0 */ VOL8 crt_vga_3b1; /* 83b1 */ VOL8 crt_vga_3b2; /* 83b2 */ @@ -136,6 +162,8 @@ typedef volatile struct _s3 { VOL8 _pad5[0x124]; /* 83e0 */ VOL16 subsys_status; /* 8504 */ VOL8 _pad6[0x6]; /* 8506 */ + VOL32 subsys_status; /* 8504 */ + VOL8 _pad6[0x4]; /* 8508 */ VOL16 adv_control; /* 850c */ VOL8 _pad7[0x1da]; /* 850e */ VOL16 cur_x; /* 86e8 */ @@ -168,10 +196,14 @@ typedef volatile struct _s3 { VOL8 _pad21[0x3fe]; /* baea */ VOL16 enh_rd_reg_dt; /* bee8 */ VOL8 _pad22[0x23fe]; /* beea */ +#else + VOL8 _pad_reg[0x5f38]; /* 83b0 */ +#endif VOL32 pix_trans; /* e2e8 */ VOL8 _pad23[0x3a974]; /* e2ec */ VOL32 alt_status_0; /* 48c60 */ + VOL32 alt_status_1; /* 48c64 */ } S3, *S3Ptr; #define VGA_STATUS_1_DTM 0x01 @@ -221,6 +253,7 @@ typedef volatile struct _s3 { #define PATTERN_L 0x8000 #define PATTERN_H 0x9000 #define PIX_CNTL 0xa000 +#define CONTROL_MISC2 0xd000 #define PIX_TRANS 0xe2e8 /* Advanced Function Control Regsiter */ @@ -339,8 +372,8 @@ typedef volatile struct _s3 { #define S3_SAVAGE4_SLOTS 0x0001ffff #define S3_SAVAGE4_2DI 0x00800000 -#define _s3WaitLoop(mask,value){ \ - int __loop = 100000; \ +#define _s3WaitLoop(s3,mask,value){ \ + int __loop = 1000000; \ while (((s3)->alt_status_0 & (mask)) != (value)) \ if (--__loop == 0) { \ ErrorF ("savage wait loop failed 0x%x\n", s3->alt_status_0); \ @@ -348,11 +381,21 @@ typedef volatile struct _s3 { } \ } -#define _s3WaitSlot(s3) _s3WaitLoop(0x1, 0x0) -#define _s3WaitEmpty(s3) _s3WaitLoop(S3_SAVAGE4_SLOTS, 0) -#define _s3WaitIdleEmpty(s3) _s3WaitLoop(S3_SAVAGE4_SLOTS|S3_SAVAGE4_2DI, \ +#define S3_SAVAGE4_ROOM 10 + +#define _s3WaitSlots(s3,n) { \ + int __loop = 1000000; \ + while (((s3)->alt_status_0 & S3_SAVAGE4_SLOTS) >= S3_SAVAGE4_ROOM-(n)) \ + if (--__loop == 0) { \ + ErrorF ("savage wait loop failed 0x%x\n", s3->alt_status_0); \ + break; \ + } \ +} + +#define _s3WaitEmpty(s3) _s3WaitLoop(s3,S3_SAVAGE4_SLOTS, 0) +#define _s3WaitIdleEmpty(s3) _s3WaitLoop(s3,S3_SAVAGE4_SLOTS|S3_SAVAGE4_2DI, \ S3_SAVAGE4_2DI) -#define _s3WaitIdle(s3) _s3WaitLoop(S3_SAVAGE4_2DI, S3_SAVAGE4_2DI) +#define _s3WaitIdle(s3) _s3WaitLoop(s3,S3_SAVAGE4_2DI, S3_SAVAGE4_2DI) typedef struct _s3Cursor { int width, height; @@ -376,14 +419,9 @@ typedef struct _s3Patterns { #define S3_CLOCK_REF 14318 /* KHz */ -#define S3_CLOCK(m,n,r) (S3_CLOCK_REF * ((m) + 2) / (((n) + 2) * (1 << (r)))) +#define S3_CLOCK(m,n,r) ((S3_CLOCK_REF * ((m) + 2)) / (((n) + 2) * (1 << (r)))) -#if PLATFORM == 200 -#define S3_MAX_CLOCK 80000 /* KHz */ -#endif -#if PLATFORM == 300 -#define S3_MAX_CLOCK 135000 /* KHz */ -#endif +#define S3_MAX_CLOCK 150000 /* KHz */ typedef struct _s3Timing { /* label */ @@ -417,6 +455,10 @@ typedef struct _s3Save { CARD32 write_mask; CARD32 fg; CARD32 bg; + CARD32 global_bitmap_1; + CARD32 global_bitmap_2; + CARD32 primary_bitmap_1; + CARD32 primary_bitmap_2; CARD8 text_save[S3_TEXT_SAVE]; } S3Save; @@ -427,6 +469,8 @@ typedef struct _s3CardInfo { CARD8 *registers; /* pointer to register map */ S3Vga s3vga; S3Save save; + Bool need_sync; + Bool bios_initialized; /* whether the bios has been run */ } S3CardInfo; typedef struct _s3ScreenInfo { @@ -438,6 +482,9 @@ typedef struct _s3ScreenInfo { int offscreen_height; /* height of offscreen area */ S3Cursor cursor; S3Patterns patterns; + Bool manage_border; + Bool managing_border; + CARD32 border_pixel; } S3ScreenInfo; #define getS3CardInfo(kd) ((S3CardInfo *) ((kd)->card->driver)) @@ -460,6 +507,7 @@ void s3RecolorCursor (ScreenPtr pScreen, int ndef, xColorItem *pdefs); Bool s3DrawInit (ScreenPtr pScreen); void s3DrawEnable (ScreenPtr pScreen); +void s3DrawSync (ScreenPtr pScreen); void s3DrawDisable (ScreenPtr pScreen); void s3DrawFini (ScreenPtr pScreen); @@ -470,10 +518,6 @@ void S3InitCard (KdCardAttr *attr); void s3GetClock (int target, int *Mp, int *Np, int *Rp, int maxM, int maxN, int maxR); -#define S3ModeClock(t) (((t->horizontal + t->hblank) * \ - (t->vertical + t->vblank) * \ - t->rate) / 1000) - extern KdCardFuncs s3Funcs; /* @@ -488,26 +532,22 @@ extern KdCardFuncs s3Funcs; #define DRAW_DEBUG(a) -#define _s3WaitVRetrace(s3) { \ - VOL8 *_status = &s3->crt_vga_status_1; \ +#define _s3WaitVRetrace(s3vga) { \ int _loop_count; \ - DRAW_DEBUG ((DEBUG_CRTC, "_s3WaitVRetrace 0x%x", *_status)); \ _loop_count = 0; \ - while ((*_status & VGA_STATUS_1_VSY) != 0) S3_RETRACE_LOOP_CHECK; \ + while (s3GetImm(s3vga, s3_vertical_sync_active) != 0) S3_RETRACE_LOOP_CHECK; \ _loop_count = 0; \ - while ((*_status & VGA_STATUS_1_VSY) == 0) S3_RETRACE_LOOP_CHECK; \ + while (s3GetImm(s3vga, s3_vertical_sync_active) == 0) S3_RETRACE_LOOP_CHECK; \ } /* * Wait for the begining of the retrace interval */ -#define _s3WaitVRetraceEnd(s3) { \ - VOL8 *_status = &s3->crt_vga_status_1; \ +#define _s3WaitVRetraceEnd(s3vga) { \ int _loop_count; \ - DRAW_DEBUG ((DEBUG_CRTC, "_s3WaitVRetraceEnd 0x%x", *_status)); \ _loop_count = 0; \ - while ((*_status & VGA_STATUS_1_VSY) == 0) S3_RETRACE_LOOP_CHECK; \ + while (s3GetImm(s3vga, s3_vertical_sync_active) == 0) S3_RETRACE_LOOP_CHECK; \ _loop_count = 0; \ - while ((*_status & VGA_STATUS_1_VSY) != 0) S3_RETRACE_LOOP_CHECK; \ + while (s3GetImm(s3vga, s3_vertical_sync_active) != 0) S3_RETRACE_LOOP_CHECK; \ } #define S3_CURSOR_WIDTH 64 @@ -516,30 +556,4 @@ extern KdCardFuncs s3Funcs; #define S3_TILE_SIZE 8 -/* - * Ok, so the S3 is broken -- it expects bitmaps to come MSB bit order, - * but it's willing to take them in LSB byte order. These macros - * flip bits around without flipping bytes. Instead of using a table - * and burning memory bandwidth, do them in place with the CPU. - */ - -/* The MIPS compiler automatically places these constants in registers */ -#define S3InvertBits32(v) { \ - v = ((v & 0x55555555) << 1) | ((v >> 1) & 0x55555555); \ - v = ((v & 0x33333333) << 2) | ((v >> 2) & 0x33333333); \ - v = ((v & 0x0f0f0f0f) << 4) | ((v >> 4) & 0x0f0f0f0f); \ -} - -#define S3InvertBits16(v) { \ - v = ((v & 0x5555) << 1) | ((v >> 1) & 0x5555); \ - v = ((v & 0x3333) << 2) | ((v >> 2) & 0x3333); \ - v = ((v & 0x0f0f) << 4) | ((v >> 4) & 0x0f0f); \ -} - -#define S3InvertBits8(v) { \ - v = ((v & 0x55) << 1) | ((v >> 1) & 0x55); \ - v = ((v & 0x33) << 2) | ((v >> 2) & 0x33); \ - v = ((v & 0x0f) << 4) | ((v >> 4) & 0x0f); \ -} - #endif /* _S3_H_ */ diff --git a/hw/kdrive/savage/s3clock.c b/hw/kdrive/savage/s3clock.c index 457f5c57e..4541362d4 100644 --- a/hw/kdrive/savage/s3clock.c +++ b/hw/kdrive/savage/s3clock.c @@ -22,7 +22,7 @@ * * Author: Keith Packard, SuSE, Inc. */ -/* $XFree86: $ */ +/* $XFree86: xc/programs/Xserver/hw/kdrive/savage/s3clock.c,v 1.1 1999/11/19 13:53:55 hohndel Exp $ */ #include "s3.h" @@ -57,7 +57,7 @@ s3GetClock (int target, int *Mp, int *Np, int *Rp, int maxM, int maxN, int maxR) for (R = 0; R <= maxR; R++) { f_vco = target * (1 << R); - if (MIN_VCO <= f_vco && f_vco < MAX_VCO) + if (f_vco >= MIN_VCO) break; } diff --git a/hw/kdrive/savage/s3cmap.c b/hw/kdrive/savage/s3cmap.c index 1c10dfa16..c0fa73e16 100644 --- a/hw/kdrive/savage/s3cmap.c +++ b/hw/kdrive/savage/s3cmap.c @@ -22,7 +22,7 @@ * * Author: Keith Packard, SuSE, Inc. */ -/* $XFree86: $ */ +/* $XFree86: xc/programs/Xserver/hw/kdrive/savage/s3cmap.c,v 1.1 1999/11/19 13:53:55 hohndel Exp $ */ #include "s3.h" @@ -31,16 +31,14 @@ s3GetColors (ScreenPtr pScreen, int ndef, xColorItem *pdefs) { KdScreenPriv(pScreen); s3CardInfo(pScreenPriv); - S3Ptr s3 = s3c->s3; - VOL8 *dac_rd_ad = &s3->crt_vga_dac_rd_ad; - VOL8 *dac_data = &s3->crt_vga_dac_data; + S3Vga *s3vga = &s3c->s3vga; while (ndef--) { - *dac_rd_ad = pdefs->pixel; - pdefs->red = *dac_data << 8; - pdefs->green = *dac_data << 8; - pdefs->blue = *dac_data << 8; + s3SetImm (s3vga, s3_dac_read_index, pdefs->pixel); + pdefs->red = s3GetImm (s3vga, s3_dac_data) << 8; + pdefs->green = s3GetImm (s3vga, s3_dac_data) << 8; + pdefs->blue = s3GetImm (s3vga, s3_dac_data) << 8; pdefs++; } } @@ -50,18 +48,40 @@ s3PutColors (ScreenPtr pScreen, int ndef, xColorItem *pdefs) { KdScreenPriv(pScreen); s3CardInfo(pScreenPriv); - S3Ptr s3 = s3c->s3; - VOL8 *dac_wt_ad = &s3->crt_vga_dac_wt_ad; - VOL8 *dac_data = &s3->crt_vga_dac_data; + s3ScreenInfo(pScreenPriv); + S3Vga *s3vga = &s3c->s3vga; + Bool hit_border = FALSE; + Bool check_border = FALSE; - _s3WaitVRetrace (s3); + _s3WaitVRetrace (s3vga); + if (pScreenPriv->enabled && s3s->manage_border && !s3s->managing_border) + check_border = TRUE; while (ndef--) { - *dac_wt_ad = pdefs->pixel; - *dac_data = pdefs->red >> 8; - *dac_data = pdefs->green >> 8; - *dac_data = pdefs->blue >> 8; + if (check_border && pdefs->pixel == s3s->border_pixel) + { + if (pdefs->red || pdefs->green || pdefs->blue) + hit_border = TRUE; + } + s3SetImm (s3vga, s3_dac_write_index, pdefs->pixel); + s3SetImm (s3vga, s3_dac_data, pdefs->red >> 8); + s3SetImm (s3vga, s3_dac_data, pdefs->green >> 8); + s3SetImm (s3vga, s3_dac_data, pdefs->blue >> 8); pdefs++; } + if (hit_border) + { + xColorItem black; + + black.red = 0; + black.green = 0; + black.blue = 0; + s3s->managing_border = TRUE; + FakeAllocColor (pScreenPriv->pInstalledmap, + &black); + s3s->border_pixel = black.pixel; + FakeFreeColor (pScreenPriv->pInstalledmap, s3s->border_pixel); +/* s3SetImm (&s3c->s3vga, s3_border_color, (VGA8) s3s->border_pixel); */ + } } diff --git a/hw/kdrive/savage/s3curs.c b/hw/kdrive/savage/s3curs.c index 0fd1397ab..cb4d79cc7 100644 --- a/hw/kdrive/savage/s3curs.c +++ b/hw/kdrive/savage/s3curs.c @@ -22,9 +22,10 @@ * * Author: Keith Packard, SuSE, Inc. */ -/* $XFree86: $ */ +/* $XFree86: xc/programs/Xserver/hw/kdrive/savage/s3curs.c,v 1.1 1999/11/19 13:53:56 hohndel Exp $ */ #include "s3.h" +#include "s3draw.h" #include "cursorstr.h" #define SetupCursor(s) KdScreenPriv(s); \ @@ -94,33 +95,9 @@ s3AllocCursorColors (ScreenPtr pScreen) { SetupCursor (pScreen); CursorPtr pCursor = pCurPriv->pCursor; - xColorItem sourceColor, maskColor; - - /* - * Set these to an invalid pixel value so that - * when the store colors comes through, the cursor - * won't get recolored - */ - pCurPriv->source = ~0; - pCurPriv->mask = ~0; - /* - * XXX S3 bug workaround; s3 chip doesn't use RGB values from - * the cursor color registers as documented, rather it uses - * them to index the DAC. This is in the errata though. - */ - sourceColor.red = pCursor->foreRed; - sourceColor.green = pCursor->foreGreen; - sourceColor.blue = pCursor->foreBlue; - FakeAllocColor(pScreenPriv->pInstalledmap, &sourceColor); - maskColor.red = pCursor->backRed; - maskColor.green = pCursor->backGreen; - maskColor.blue = pCursor->backBlue; - FakeAllocColor(pScreenPriv->pInstalledmap, &maskColor); - FakeFreeColor(pScreenPriv->pInstalledmap, sourceColor.pixel); - FakeFreeColor(pScreenPriv->pInstalledmap, maskColor.pixel); - pCurPriv->source = sourceColor.pixel; - pCurPriv->mask = maskColor.pixel; + KdAllocateCursorPixels (pScreen, pCursor, + &pCurPriv->source, &pCurPriv->mask); switch (pScreenPriv->screen->bitsPerPixel) { case 4: pCurPriv->source |= pCurPriv->source << 4; @@ -190,8 +167,9 @@ s3LoadCursor (ScreenPtr pScreen, int x, int y) CursorBitsPtr bits = pCursor->bits; int w, h; unsigned char r[2], g[2], b[2]; - unsigned short *ram, *msk, *mskLine, *src, *srcLine; - unsigned short and, xor; + unsigned long *ram; + unsigned long *msk, *mskLine, *src, *srcLine; + unsigned long and, xor; int i, j; int cursor_address; int wsrc; @@ -209,24 +187,24 @@ s3LoadCursor (ScreenPtr pScreen, int x, int y) /* * Stick new image into cursor memory */ - ram = (unsigned short *) s3s->cursor_base; - mskLine = (unsigned short *) bits->mask; - srcLine = (unsigned short *) bits->source; + ram = (unsigned long *) s3s->cursor_base; + mskLine = (unsigned long *) bits->mask; + srcLine = (unsigned long *) bits->source; h = bits->height; if (h > S3_CURSOR_HEIGHT) h = S3_CURSOR_HEIGHT; - wsrc = BitmapBytePad(bits->width) / 2; /* words per line */ + wsrc = BitmapBytePad(bits->width) / 4; /* ulongs per line */ for (i = 0; i < S3_CURSOR_HEIGHT; i++) { msk = mskLine; src = srcLine; mskLine += wsrc; srcLine += wsrc; - for (j = 0; j < S3_CURSOR_WIDTH / 16; j++) { + for (j = 0; j < S3_CURSOR_WIDTH / 32; j++) { - unsigned short m, s; + unsigned long m, s; if (i < h && j < wsrc) { @@ -237,14 +215,14 @@ s3LoadCursor (ScreenPtr pScreen, int x, int y) } else { - and = 0xffff; - xor = 0x0000; + and = 0xffffffff; + xor = 0x00000000; } - S3InvertBits16(and); - *ram++ = and; - S3InvertBits16(xor); - *ram++ = xor; + S3AdjustBits32(and); + S3AdjustBits32(xor); + *ram++ = (and & 0xffff) | (xor << 16); + *ram++ = (and >> 16) | (xor & 0xffff0000); } } @@ -254,10 +232,11 @@ s3LoadCursor (ScreenPtr pScreen, int x, int y) _s3SetCursorColors (pScreen); /* Enable the cursor */ + s3SetImm (s3vga, s3_cursor_ms_x11, 0); s3SetImm (s3vga, s3_cursor_enable, 1); /* Wait for VRetrace to make sure the position is read */ - _s3WaitVRetrace (s3); + _s3WaitVRetrace (s3vga); /* Move to new position */ _s3MoveCursor (pScreen, x, y); @@ -285,7 +264,11 @@ s3RealizeCursor (ScreenPtr pScreen, CursorPtr pCursor) { if (pCursor) { - int x, y; +#ifdef FB_OLD_SCREEN + short x, y; +#else + int x, y; +#endif miPointerPosition (&x, &y); s3LoadCursor (pScreen, x, y); @@ -382,7 +365,11 @@ s3CursorEnable (ScreenPtr pScreen) { if (pCurPriv->pCursor) { - int x, y; +#ifdef FB_OLD_SCREEN + short x, y; +#else + int x, y; +#endif miPointerPosition (&x, &y); s3LoadCursor (pScreen, x, y); diff --git a/hw/kdrive/savage/s3draw.c b/hw/kdrive/savage/s3draw.c index c57bc2eb5..2d86caaa9 100644 --- a/hw/kdrive/savage/s3draw.c +++ b/hw/kdrive/savage/s3draw.c @@ -22,7 +22,7 @@ * * Author: Keith Packard, SuSE, Inc. */ -/* $XFree86: $ */ +/* $XFree86: xc/programs/Xserver/hw/kdrive/savage/s3draw.c,v 1.1 1999/11/19 13:53:56 hohndel Exp $ */ #include "s3.h" #include "s3draw.h" @@ -69,12 +69,12 @@ short s3alu[16] = { #define BURST #ifdef BURST #define PixTransDeclare VOL32 *pix_trans_base = (VOL32 *) (s3c->registers),\ - *pix_trans = pix_trans_base; -#define PixTransStart(n) if (pix_trans + (n) > pix_trans_base + 8192) pix_trans = pix_trans_base; + *pix_trans = pix_trans_base +#define PixTransStart(n) if (pix_trans + (n) > pix_trans_base + 8192) pix_trans = pix_trans_base #define PixTransStore(t) *pix_trans++ = (t) #else -#define PixTransDeclare VOL32 *pix_trans = &s3->pix_trans; -#define PixTransStart(n) +#define PixTransDeclare VOL32 *pix_trans = &s3->pix_trans +#define PixTransStart(n) #define PixTransStore(t) *pix_trans = (t) #endif @@ -147,14 +147,14 @@ s3CopyNtoN (DrawablePtr pSrcDrawable, _s3Blt (s3, srcX, srcY, dstX, dstY, w, h, flags); pbox++; } - _s3WaitIdleEmpty(s3); + MarkSyncS3 (pSrcDrawable->pScreen); } RegionPtr s3CopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC, int srcx, int srcy, int width, int height, int dstx, int dsty) { - KdScreenPriv(pDstDrawable->pScreen); + SetupS3(pDstDrawable->pScreen); if (pSrcDrawable->type == DRAWABLE_WINDOW && pDstDrawable->type == DRAWABLE_WINDOW) @@ -163,12 +163,13 @@ s3CopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC, srcx, srcy, width, height, dstx, dsty, s3CopyNtoN, 0, 0); } - return fbCopyArea (pSrcDrawable, pDstDrawable, pGC, - srcx, srcy, width, height, dstx, dsty); + return KdCheckCopyArea (pSrcDrawable, pDstDrawable, pGC, + srcx, srcy, width, height, dstx, dsty); } typedef struct _s31toNargs { unsigned long copyPlaneFG, copyPlaneBG; + Bool opaque; } s31toNargs; void @@ -209,7 +210,7 @@ _s3Stipple (S3CardInfo *s3c, while (nl--) { tmp = *psrc++; - S3InvertBits32(tmp); + S3AdjustBits32 (tmp); PixTransStore (tmp); } psrc += widthRest; @@ -228,7 +229,7 @@ _s3Stipple (S3CardInfo *s3c, tmp = FbStipLeft(bits, leftShift); bits = *psrc++; tmp |= FbStipRight(bits, rightShift); - S3InvertBits32(tmp); + S3AdjustBits32(tmp); PixTransStore (tmp); } psrc += widthRest; @@ -257,7 +258,7 @@ s3Copy1toN (DrawablePtr pSrcDrawable, FbStride widthSrc; int srcBpp; - if (sourceInvarient (pGC->alu)) + if (args->opaque && sourceInvarient (pGC->alu)) { s3FillBoxSolid (pDstDrawable, nbox, pbox, pGC->bgPixel, pGC->alu, pGC->planemask); @@ -266,8 +267,16 @@ s3Copy1toN (DrawablePtr pSrcDrawable, fbGetStipDrawable (pSrcDrawable, psrcBase, widthSrc, srcBpp); - _s3SetOpaquePlaneBlt(s3,pGC->alu,pGC->planemask,args->copyPlaneFG, - args->copyPlaneBG); + if (args->opaque) + { + _s3SetOpaquePlaneBlt(s3,pGC->alu,pGC->planemask,args->copyPlaneFG, + args->copyPlaneBG); + } + else + { + _s3SetTransparentPlaneBlt (s3, pGC->alu, + pGC->planemask, args->copyPlaneFG); + } while (nbox--) { @@ -281,7 +290,7 @@ s3Copy1toN (DrawablePtr pSrcDrawable, pbox->x2 - dstx, pbox->y2 - dsty); pbox++; } - _s3WaitIdleEmpty (s3); + MarkSyncS3 (pDstDrawable->pScreen); } RegionPtr @@ -289,7 +298,7 @@ s3CopyPlane(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC, int srcx, int srcy, int width, int height, int dstx, int dsty, unsigned long bitPlane) { - KdScreenPriv (pDstDrawable->pScreen); + SetupS3 (pDstDrawable->pScreen); RegionPtr ret; s31toNargs args; @@ -298,13 +307,35 @@ s3CopyPlane(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC, { args.copyPlaneFG = pGC->fgPixel; args.copyPlaneBG = pGC->bgPixel; + args.opaque = TRUE; return fbDoCopy (pSrcDrawable, pDstDrawable, pGC, srcx, srcy, width, height, dstx, dsty, s3Copy1toN, bitPlane, &args); } - return fbCopyPlane(pSrcDrawable, pDstDrawable, pGC, - srcx, srcy, width, height, - dstx, dsty, bitPlane); + return KdCheckCopyPlane(pSrcDrawable, pDstDrawable, pGC, + srcx, srcy, width, height, + dstx, dsty, bitPlane); +} + +void +s3PushPixels (GCPtr pGC, PixmapPtr pBitmap, + DrawablePtr pDrawable, + int w, int h, int x, int y) +{ + SetupS3 (pDrawable->pScreen); + s31toNargs args; + + if (pDrawable->type == DRAWABLE_WINDOW && pGC->fillStyle == FillSolid) + { + args.opaque = FALSE; + args.copyPlaneFG = pGC->fgPixel; + (void) fbDoCopy ((DrawablePtr) pBitmap, pDrawable, pGC, + 0, 0, w, h, x, y, s3Copy1toN, 1, &args); + } + else + { + KdCheckPushPixels (pGC, pBitmap, pDrawable, w, h, x, y); + } } void @@ -320,7 +351,7 @@ s3FillBoxSolid (DrawablePtr pDrawable, int nBox, BoxPtr pBox, _s3SolidRect(s3,pBox->x1,pBox->y1,pBox->x2-pBox->x1,pBox->y2-pBox->y1); pBox++; } - _s3WaitIdleEmpty(s3); + MarkSyncS3 (pDrawable->pScreen); } void @@ -363,7 +394,7 @@ s3FillBoxPattern (DrawablePtr pDrawable, int nBox, BoxPtr pBox, pBox->x2-pBox->x1, pBox->y2-pBox->y1); pBox++; } - _s3WaitIdleEmpty(s3); + MarkSyncS3 (pDrawable->pScreen); } void @@ -438,7 +469,7 @@ s3FillBoxLargeStipple (DrawablePtr pDrawable, GCPtr pGC, stipY = 0; } } - _s3WaitIdleEmpty (s3); + MarkSyncS3 (pDrawable->pScreen); } #define NUM_STACK_RECTS 1024 @@ -669,7 +700,7 @@ s3FillSpans (DrawablePtr pDrawable, GCPtr pGC, int n, { s3GCPrivate(pGC); SetupS3(pDrawable->pScreen); - int x, y; + int x, y, x1, y1, x2, y2; int width; /* next three parameters are post-clip */ int nTmp; @@ -678,60 +709,113 @@ s3FillSpans (DrawablePtr pDrawable, GCPtr pGC, int n, FbGCPrivPtr fbPriv = fbGetGCPrivate(pGC); BoxPtr extents; S3PatternCache *cache; + RegionPtr pClip = fbGetCompositeClip (pGC); - nTmp = n * miFindMaxBand(fbGetCompositeClip(pGC)); - pwidthFree = (int *)ALLOCATE_LOCAL(nTmp * sizeof(int)); - pptFree = (DDXPointRec *)ALLOCATE_LOCAL(nTmp * sizeof(DDXPointRec)); - if(!pptFree || !pwidthFree) + if (REGION_NUM_RECTS(pClip) == 1 && + (pGC->fillStyle == FillSolid || s3Priv->pPattern)) { - if (pptFree) DEALLOCATE_LOCAL(pptFree); - if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree); - return; - } - n = miClipSpans(fbGetCompositeClip(pGC), - ppt, pwidth, n, - pptFree, pwidthFree, fSorted); - pwidth = pwidthFree; - ppt = pptFree; - if (pGC->fillStyle == FillSolid) - { - _s3SetSolidFill(s3,pGC->fgPixel,pGC->alu,pGC->planemask); + extents = REGION_RECTS(pClip); + x1 = extents->x1; + x2 = extents->x2; + y1 = extents->y1; + y2 = extents->y2; + if (pGC->fillStyle == FillSolid) + { + _s3SetSolidFill(s3,pGC->fgPixel,pGC->alu,pGC->planemask); + cache = 0; + } + else + { + _s3SetPattern (pDrawable->pScreen, pGC->alu, pGC->planemask, + s3Priv->pPattern); + cache = s3Priv->pPattern->cache; + } while (n--) { - x = ppt->x; y = ppt->y; - ppt++; - width = *pwidth++; - if (width) + if (y1 <= y && y < y2) { - _s3SolidRect(s3,x,y,width,1); + x = ppt->x; + width = *pwidth; + if (x < x1) + { + width -= (x1 - x); + x = x1; + } + if (x2 < x + width) + width = x2 - x; + if (width > 0) + { + if (cache) + { + _s3PatRect(s3, cache->x, cache->y, x, y, width, 1); + } + else + { + _s3SolidRect(s3,x,y,width,1); + } + } } + ppt++; + pwidth++; } } - else if (s3Priv->pPattern) + else { - _s3SetPattern (pDrawable->pScreen, pGC->alu, pGC->planemask, - s3Priv->pPattern); - cache = s3Priv->pPattern->cache; - while (n--) + nTmp = n * miFindMaxBand(pClip); + pwidthFree = (int *)ALLOCATE_LOCAL(nTmp * sizeof(int)); + pptFree = (DDXPointRec *)ALLOCATE_LOCAL(nTmp * sizeof(DDXPointRec)); + if(!pptFree || !pwidthFree) { - x = ppt->x; - y = ppt->y; - ppt++; - width = *pwidth++; - if (width) + if (pptFree) DEALLOCATE_LOCAL(pptFree); + if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree); + return; + } + n = miClipSpans(fbGetCompositeClip(pGC), + ppt, pwidth, n, + pptFree, pwidthFree, fSorted); + pwidth = pwidthFree; + ppt = pptFree; + if (pGC->fillStyle == FillSolid) + { + _s3SetSolidFill(s3,pGC->fgPixel,pGC->alu,pGC->planemask); + while (n--) { - _s3PatRect(s3, cache->x, cache->y, x, y, width, 1); + x = ppt->x; + y = ppt->y; + ppt++; + width = *pwidth++; + if (width) + { + _s3SolidRect(s3,x,y,width,1); + } } } + else if (s3Priv->pPattern) + { + _s3SetPattern (pDrawable->pScreen, pGC->alu, pGC->planemask, + s3Priv->pPattern); + cache = s3Priv->pPattern->cache; + while (n--) + { + x = ppt->x; + y = ppt->y; + ppt++; + width = *pwidth++; + if (width) + { + _s3PatRect(s3, cache->x, cache->y, x, y, width, 1); + } + } + } + else + { + _s3FillSpanLargeStipple (pDrawable, pGC, n, ppt, pwidth); + } + DEALLOCATE_LOCAL(pptFree); + DEALLOCATE_LOCAL(pwidthFree); } - else - { - _s3FillSpanLargeStipple (pDrawable, pGC, n, ppt, pwidth); - } - _s3WaitIdleEmpty (s3); - DEALLOCATE_LOCAL(pptFree); - DEALLOCATE_LOCAL(pwidthFree); + MarkSyncS3 (pDrawable->pScreen); } #include "mifillarc.h" @@ -886,14 +970,14 @@ s3PolyFillArcSolid (DrawablePtr pDraw, GCPtr pGC, int narcs, xArc *parcs) } if (set) { - _s3WaitIdleEmpty(s3); + MarkSyncS3 (pDraw->pScreen); set = FALSE; } - miPolyFillArc(pDraw, pGC, 1, parcs); + KdCheckPolyFillArc(pDraw, pGC, 1, parcs); } if (set) { - _s3WaitIdleEmpty(s3); + MarkSyncS3 (pDraw->pScreen); set = FALSE; } } @@ -925,7 +1009,7 @@ s3FillPoly1Rect (DrawablePtr pDrawable, GCPtr pGC, int shape, if (mode == CoordModePrevious) { - miFillPolygon (pDrawable, pGC, shape, mode, countInit, ptsIn); + KdCheckFillPolygon (pDrawable, pGC, shape, mode, countInit, ptsIn); return; } @@ -949,7 +1033,7 @@ s3FillPoly1Rect (DrawablePtr pDrawable, GCPtr pGC, int shape, */ if (c & 0xe000e000) { - miFillPolygon (pDrawable, pGC, shape, mode, countInit, ptsIn); + KdCheckFillPolygon (pDrawable, pGC, shape, mode, countInit, ptsIn); return; } c = intToY(c); @@ -979,7 +1063,7 @@ s3FillPoly1Rect (DrawablePtr pDrawable, GCPtr pGC, int shape, */ if (c & 0xe000e000) { - miFillPolygon (pDrawable, pGC, shape, mode, countInit, ptsIn); + KdCheckFillPolygon (pDrawable, pGC, shape, mode, countInit, ptsIn); return; } c = intToY(c); @@ -1016,7 +1100,7 @@ s3FillPoly1Rect (DrawablePtr pDrawable, GCPtr pGC, int shape, yFlip++; if (yFlip != 2) { - miFillPolygon (pDrawable, pGC, shape, mode, countInit, ptsIn); + KdCheckFillPolygon (pDrawable, pGC, shape, mode, countInit, ptsIn); return; } } @@ -1141,7 +1225,7 @@ s3FillPoly1Rect (DrawablePtr pDrawable, GCPtr pGC, int shape, break; } _s3ResetClip (s3, pDrawable->pScreen); - _s3WaitIdleEmpty(s3); + MarkSyncS3 (pDrawable->pScreen); } void @@ -1171,7 +1255,7 @@ s3PolyGlyphBltClipped (DrawablePtr pDrawable, int nbox; int x1, y1, x2, y2; unsigned char alu; - Bool locked; + Bool set; PixTransDeclare; x += pDrawable->x; @@ -1229,10 +1313,10 @@ s3PolyGlyphBltClipped (DrawablePtr pDrawable, _s3SolidRect (s3, x1, y1, x2 - x1, y2 - y1); } } + MarkSyncS3 (pDrawable->pScreen); } - _s3SetTransparentPlaneBlt (s3, alu, pGC->planemask, pGC->fgPixel); ppci = ppciInit; - locked = TRUE; + set = FALSE; while (nglyph--) { pci = *ppci++; @@ -1247,13 +1331,14 @@ s3PolyGlyphBltClipped (DrawablePtr pDrawable, switch (RECT_IN_REGION(pGC->pScreen, pClip, &bbox)) { case rgnIN: +#if 1 lw = h * ((w + 31) >> 5); if (lw) { - if (!locked) + if (!set) { _s3SetTransparentPlaneBlt (s3, alu, pGC->planemask, pGC->fgPixel); - locked = TRUE; + set = TRUE; } _s3PlaneBlt(s3, x + pci->metrics.leftSideBearing, @@ -1264,17 +1349,16 @@ s3PolyGlyphBltClipped (DrawablePtr pDrawable, while (lw--) { b = *bits++; - S3InvertBits32 (b); + S3AdjustBits32 (b); PixTransStore(b); } + MarkSyncS3 (pDrawable->pScreen); } break; +#endif case rgnPART: - if (locked) - { - _s3WaitIdleEmpty(s3); - locked = FALSE; - } + set = FALSE; + CheckSyncS3 (pDrawable->pScreen); fbPutXYImage (pDrawable, pClip, fbPriv->fg, @@ -1293,7 +1377,6 @@ s3PolyGlyphBltClipped (DrawablePtr pDrawable, } x += pci->metrics.characterWidth; } - _s3WaitIdleEmpty(s3); } /* @@ -1422,13 +1505,13 @@ s3PolyGlyphBlt (DrawablePtr pDrawable, while (lw--) { b = *bits++; - S3InvertBits32 (b); + S3AdjustBits32 (b); PixTransStore(b); } } x += pci->metrics.characterWidth; } - _s3WaitIdleEmpty(s3); + MarkSyncS3 (pDrawable->pScreen); } void @@ -1487,6 +1570,8 @@ s3ImageTEGlyphBlt (DrawablePtr pDrawable, GCPtr pGC, switch (RECT_IN_REGION(pGC->pScreen, fbGetCompositeClip(pGC), &bbox)) { + case rgnIN: + break; case rgnPART: if (pglyphBase == (pointer) 1) pglyphBase = 0; @@ -1510,6 +1595,12 @@ s3ImageTEGlyphBlt (DrawablePtr pDrawable, GCPtr pGC, _s3SetOpaquePlaneBlt (s3, GXcopy, pGC->planemask, pGC->fgPixel, pGC->bgPixel); } +#if BITMAP_BIT_ORDER == LSBFirst +#define SHIFT << +#else +#define SHIFT >> +#endif + #define LoopIt(count, w, loadup, fetch) \ while (nglyph >= count) \ { \ @@ -1521,7 +1612,7 @@ s3ImageTEGlyphBlt (DrawablePtr pDrawable, GCPtr pGC, PixTransStart(h); \ while (lwTmp--) { \ tmp = fetch; \ - S3InvertBits32(tmp); \ + S3AdjustBits32(tmp); \ PixTransStore(tmp); \ } \ } @@ -1535,9 +1626,9 @@ s3ImageTEGlyphBlt (DrawablePtr pDrawable, GCPtr pGC, char3 = (unsigned long *) (*ppci++)->bits; char4 = (unsigned long *) (*ppci++)->bits;, (*char1++ | ((*char2++ | ((*char3++ | (*char4++ - << widthGlyph)) - << widthGlyph)) - << widthGlyph))) + SHIFT widthGlyph)) + SHIFT widthGlyph)) + SHIFT widthGlyph))) } else if (widthGlyph <= 10) { @@ -1546,7 +1637,7 @@ s3ImageTEGlyphBlt (DrawablePtr pDrawable, GCPtr pGC, char1 = (unsigned long *) (*ppci++)->bits; char2 = (unsigned long *) (*ppci++)->bits; char3 = (unsigned long *) (*ppci++)->bits;, - (*char1++ | ((*char2++ | (*char3++ << widthGlyph)) << widthGlyph))) + (*char1++ | ((*char2++ | (*char3++ SHIFT widthGlyph)) SHIFT widthGlyph))) } else if (widthGlyph <= 16) { @@ -1554,7 +1645,7 @@ s3ImageTEGlyphBlt (DrawablePtr pDrawable, GCPtr pGC, LoopIt(2, widthGlyphs, char1 = (unsigned long *) (*ppci++)->bits; char2 = (unsigned long *) (*ppci++)->bits;, - (*char1++ | (*char2++ << widthGlyph))) + (*char1++ | (*char2++ SHIFT widthGlyph))) } lw = h * ((widthGlyph + 31) >> 5); while (nglyph--) @@ -1567,11 +1658,11 @@ s3ImageTEGlyphBlt (DrawablePtr pDrawable, GCPtr pGC, while (lwTmp--) { tmp = *char1++; - S3InvertBits32(tmp); + S3AdjustBits32(tmp); PixTransStore(tmp); } } - _s3WaitIdleEmpty (s3); + MarkSyncS3 (pDrawable->pScreen); } void @@ -1583,15 +1674,6 @@ s3PolyTEGlyphBlt (DrawablePtr pDrawable, GCPtr pGC, s3ImageTEGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, (pointer) 1); } -#define _s3ClipLine(s3,cmd,e1,e2,e,len) {\ - DRAW_DEBUG ((DEBUG_RENDER, "clip line 0x%x 0x%x 0x%x 0x%x 0x%x", cmd,e1,e2,e,len)); \ - _s3CmdWait(s3); \ - _s3SetPcnt (s3, (len), 0); \ - _s3SetStep (s3, e2, e1); \ - _s3SetErr (s3, e); \ - _s3SetCmd (s3, CMD_LINE | (cmd) | DRAW | WRTDATA); \ -} - void _s3Segment (DrawablePtr pDrawable, GCPtr pGC, @@ -1750,7 +1832,7 @@ s3Polylines (DrawablePtr pDrawable, GCPtr pGC, x = nx; y = ny; } - _s3WaitIdleEmpty(s3); + MarkSyncS3 (pDrawable->pScreen); } void @@ -1781,7 +1863,7 @@ s3PolySegment (DrawablePtr pDrawable, GCPtr pGC, pSeg->x2 + ox, pSeg->y2 + oy, drawLast); } - _s3WaitIdleEmpty(s3); + MarkSyncS3 (pDrawable->pScreen); } /* @@ -1939,6 +2021,8 @@ _s3PutPattern (ScreenPtr pScreen, s3PatternPtr pPattern) cache->y * pScreenPriv->screen->byteStride + cache->x * pScreenPriv->bytesPerPixel); + CheckSyncS3 (pScreen); + for (y = 0; y < S3_TILE_SIZE; y++) { switch (pScreenPriv->screen->bitsPerPixel) { @@ -2094,7 +2178,7 @@ s3ChangeWindowAttributes (WindowPtr pWin, Mask mask) void s3PaintWindow(WindowPtr pWin, RegionPtr pRegion, int what) { - KdScreenPriv(pWin->drawable.pScreen); + SetupS3(pWin->drawable.pScreen); s3PatternPtr pPattern; DRAW_DEBUG ((DEBUG_PAINT_WINDOW, "s3PaintWindow 0x%x extents %d %d %d %d n %d", @@ -2146,7 +2230,7 @@ s3PaintWindow(WindowPtr pWin, RegionPtr pRegion, int what) } break; } - fbPaintWindow (pWin, pRegion, what); + KdCheckPaintWindow (pWin, pRegion, what); } void @@ -2198,7 +2282,7 @@ s3CopyWindowProc (DrawablePtr pSrcDrawable, _s3Blt (s3, srcX, srcY, dstX, dstY, w, h, flags); pbox++; } - _s3WaitIdleEmpty(s3); + MarkSyncS3 (pDstDrawable->pScreen); } void @@ -2255,6 +2339,10 @@ s3DrawInit (ScreenPtr pScreen) if (!AllocateGCPrivate(pScreen, s3GCPrivateIndex, sizeof (s3PrivGCRec))) return FALSE; /* + * Hook up asynchronous drawing + */ + RegisterSync (pScreen); + /* * Replace various fb screen functions */ pScreen->CreateGC = s3CreateGC; @@ -2306,17 +2394,19 @@ s3DrawEnable (ScreenPtr pScreen) for (c = 0; c < s3s->patterns.ncache; c++) s3s->patterns.cache[c].id = 0; - _s3WaitIdleEmpty(s3); + _s3WaitIdleEmpty (s3); _s3SetScissorsTl(s3, 0, 0); _s3SetScissorsBr(s3, pScreenPriv->screen->width - 1, pScreenPriv->screen->height - 1); _s3SetSolidFill(s3, pScreen->blackPixel, GXcopy, ~0); _s3SolidRect (s3, 0, 0, pScreenPriv->screen->width, pScreenPriv->screen->height); - _s3WaitIdleEmpty (s3); + MarkSyncS3 (pScreen); } void s3DrawDisable (ScreenPtr pScreen) { + SetupS3 (pScreen); + _s3WaitIdleEmpty (s3); } void @@ -2332,3 +2422,11 @@ s3DrawFini (ScreenPtr pScreen) s3s->patterns.ncache = 0; } } + +void +s3DrawSync (ScreenPtr pScreen) +{ + SetupS3(pScreen); + + _s3WaitIdleEmpty(s3c->s3); +} diff --git a/hw/kdrive/savage/s3draw.h b/hw/kdrive/savage/s3draw.h index 14dd1688e..80b1b1150 100644 --- a/hw/kdrive/savage/s3draw.h +++ b/hw/kdrive/savage/s3draw.h @@ -22,7 +22,7 @@ * * Author: Keith Packard, SuSE, Inc. */ -/* $XFree86: $ */ +/* $XFree86: xc/programs/Xserver/hw/kdrive/savage/s3draw.h,v 1.1 1999/11/19 13:53:56 hohndel Exp $ */ #ifndef _S3DRAW_H_ #define _S3DRAW_H_ @@ -62,9 +62,69 @@ void _s3LoadPattern (ScreenPtr pScreen, s3PatternPtr pPattern); s3CardInfo(pScreenPriv); \ S3Ptr s3 = s3c->s3 +#ifdef S3_SYNC_DEBUG +#define SYNC_DEBUG() fprintf (stderr, "Sync at %s:%d\n", __FILE__,__LINE__) +#else +#define SYNC_DEBUG() +#endif + +#define S3_ASYNC +#ifdef S3_ASYNC +#define CheckSyncS3(s) KdCheckSync(s) +#define MarkSyncS3(s) KdMarkSync(s) +#define RegisterSync(screen) KdScreenInitAsync (screen) +#else +#define CheckSyncS3(s3c) +#define MarkSyncS3(s3c) _s3WaitIdleEmpty(s3c->s3) +#define RegisterSync(screen) +#endif + #define WIDEN(x) ((unsigned long) (x)) #define MERGE(a,b) ((WIDEN(a) << 16) | WIDEN(b)) +/* + * Ok, so the S3 is broken -- it expects bitmaps to come MSB bit order, + * but it's willing to take them in LSB byte order. These macros + * flip bits around without flipping bytes. Instead of using a table + * and burning memory bandwidth, do them in place with the CPU. + */ + +/* The MIPS compiler automatically places these constants in registers */ +#define S3InvertBits32(v) { \ + v = ((v & 0x55555555) << 1) | ((v >> 1) & 0x55555555); \ + v = ((v & 0x33333333) << 2) | ((v >> 2) & 0x33333333); \ + v = ((v & 0x0f0f0f0f) << 4) | ((v >> 4) & 0x0f0f0f0f); \ +} + +#define S3InvertBits16(v) { \ + v = ((v & 0x5555) << 1) | ((v >> 1) & 0x5555); \ + v = ((v & 0x3333) << 2) | ((v >> 2) & 0x3333); \ + v = ((v & 0x0f0f) << 4) | ((v >> 4) & 0x0f0f); \ +} + +#define S3InvertBits8(v) { \ + v = ((v & 0x55) << 1) | ((v >> 1) & 0x55); \ + v = ((v & 0x33) << 2) | ((v >> 2) & 0x33); \ + v = ((v & 0x0f) << 4) | ((v >> 4) & 0x0f); \ +} + +#define S3ByteSwap32(x) ((x) = (((x) >> 24) | \ + (((x) >> 8) & 0xff00) | \ + (((x) << 8) & 0xff0000) | \ + ((x) << 24))) + +#define S3ByteSwap16(x) ((x) = ((x) << 8) | ((x) >> 8)) + +#if BITMAP_BIT_ORDER == LSBFirst +#define S3AdjustBits32(x) S3InvertBits32(x) +#define S3AdjustBits16(x) S3InvertBits16(x) +#else +#define S3AdjustBits32(x) S3ByteSwap32(x) +#define S3AdjustBits16(x) S3ByteSwap16(x) +#endif + +#define _s3WaitSlot(s3) _s3WaitSlots(s3,1) + #define _s3SetFg(s3,_fg) { \ DRAW_DEBUG ((DEBUG_REGISTERS, " fg <- 0x%x", _fg));\ s3->fg = (_fg); \ @@ -87,7 +147,7 @@ void _s3LoadPattern (ScreenPtr pScreen, s3PatternPtr pPattern); #define _s3SetPixelControl(s3,_ctl) { \ DRAW_DEBUG((DEBUG_REGISTERS, " pix_cntl <- 0x%x", PIX_CNTL | (_ctl))); \ - s3->pix_cntl = PIX_CNTL | (_ctl); \ + s3->pix_cntl_mult_misc2 = MERGE (CONTROL_MISC2, PIX_CNTL | (_ctl)); \ } #define _s3SetFgMix(s3,_mix) { \ @@ -141,11 +201,12 @@ void _s3LoadPattern (ScreenPtr pScreen, s3PatternPtr pPattern); DRAW_DEBUG((DEBUG_REGISTERS, " cmd <- 0x%x", _cmd)); \ _s3CmdWait(s3); \ s3->cmd_gp_stat = (_cmd); \ - { CARD32 __junk__; __junk__ = s3->cmd_gp_stat; } \ + /* { CARD32 __junk__; __junk__ = s3->cmd_gp_stat; } */ \ } #define _s3SetSolidFill(s3,pix,alu,mask) { \ DRAW_DEBUG((DEBUG_SET,"set fill 0x%x %d 0x%x",pix,alu,mask)); \ + _s3WaitSlots(s3,4); \ _s3SetFg (s3, pix); \ _s3SetWriteMask(s3,mask); \ _s3SetMix (s3, FSS_FRGDCOL | s3alu[alu], BSS_BKGDCOL | MIX_SRC); \ @@ -155,7 +216,7 @@ void _s3LoadPattern (ScreenPtr pScreen, s3PatternPtr pPattern); #define _s3SolidRect(s3,x,y,w,h) {\ DRAW_DEBUG((DEBUG_RENDER,"solid rect %d,%d %dx%d",x,y,w,h)); \ - _s3CmdWait(s3); \ + _s3WaitSlots(s3,3); \ _s3SetCur(s3, x, y); \ _s3SetPcnt (s3, (w)-1, (h)-1); \ _s3SetCmd (s3, CMD_RECT|INC_X|INC_Y|DRAW|WRTDATA); \ @@ -164,15 +225,25 @@ void _s3LoadPattern (ScreenPtr pScreen, s3PatternPtr pPattern); #define _s3SolidLine(s3,maj,min,len,cmd) { \ DRAW_DEBUG ((DEBUG_RENDER, "solid line 0x%x 0x%x 0x%x", maj, min, cmd)); \ - _s3CmdWait(s3); \ + _s3WaitSlots(s3,4); \ _s3SetPcnt(s3, (len), 0); \ _s3SetStep(s3, 2*((min) - (maj)), 2*(min)); \ _s3SetErr(s3, 2*(min) - (maj)); \ _s3SetCmd (s3, CMD_LINE | (cmd) | DRAW | WRTDATA); \ } +#define _s3ClipLine(s3,cmd,e1,e2,e,len) {\ + DRAW_DEBUG ((DEBUG_RENDER, "clip line 0x%x 0x%x 0x%x 0x%x 0x%x", cmd,e1,e2,e,len)); \ + _s3WaitSlots(s3, 4); \ + _s3SetPcnt (s3, (len), 0); \ + _s3SetStep (s3, e2, e1); \ + _s3SetErr (s3, e); \ + _s3SetCmd (s3, CMD_LINE | (cmd) | DRAW | WRTDATA); \ +} + #define _s3SetTile(s3,alu,mask) { \ DRAW_DEBUG ((DEBUG_SET,"set tile %d 0x%x", alu, mask)); \ + _s3WaitSlots(s3,3); \ _s3SetWriteMask(s3, mask); \ _s3SetMix(s3, FSS_BITBLT | s3alu[alu], BSS_BITBLT|s3alu[alu]); \ _s3SetPixelControl (s3, MIXSEL_FRGDMIX); \ @@ -185,6 +256,7 @@ void _s3LoadPattern (ScreenPtr pScreen, s3PatternPtr pPattern); */ #define _s3SetStipple(s3,alu,mask,_fg) {\ DRAW_DEBUG ((DEBUG_SET,"set stipple 0x%x %d 0x%x", _fg, alu, mask)); \ + _s3WaitSlots(s3,5); \ _s3SetFg (s3, _fg); \ _s3SetBg (s3, 0); \ _s3SetWriteMask(s3,mask); \ @@ -195,6 +267,7 @@ void _s3LoadPattern (ScreenPtr pScreen, s3PatternPtr pPattern); #define _s3SetOpaqueStipple(s3,alu,mask,_fg,_bg) {\ DRAW_DEBUG ((DEBUG_SET,"set opaque stipple 0x%x 0x%x %d 0x%x", _fg, _bg, alu, mask)); \ + _s3WaitSlots(s3,5); \ _s3SetFg (s3, _fg); \ _s3SetBg (s3, _bg); \ _s3SetWriteMask(s3,mask); \ @@ -205,7 +278,7 @@ void _s3LoadPattern (ScreenPtr pScreen, s3PatternPtr pPattern); #define _s3PatRect(s3,px,py,x,y,w,h) {\ DRAW_DEBUG ((DEBUG_RENDER, "pat rect %d,%d %dx%d", x,y,w,h)); \ - _s3CmdWait(s3); \ + _s3WaitSlots(s3, 4); \ _s3SetCur (s3, px, py); \ _s3SetStep (s3, x, y); \ _s3SetPcnt (s3, (w)-1, (h)-1); \ @@ -215,6 +288,7 @@ void _s3LoadPattern (ScreenPtr pScreen, s3PatternPtr pPattern); #define _s3SetBlt(s3,alu,mask) { \ DRAW_DEBUG ((DEBUG_SET,"set blt %d 0x%x", alu, mask)); \ + _s3WaitSlots(s3,3); \ _s3SetPixelControl (s3, MIXSEL_FRGDMIX); \ _s3SetMix(s3, FSS_BITBLT | s3alu[alu], BSS_BITBLT | s3alu[alu]); \ _s3SetWriteMask(s3, mask); \ @@ -224,7 +298,7 @@ void _s3LoadPattern (ScreenPtr pScreen, s3PatternPtr pPattern); #define _s3Blt(s3,_sx,_sy,_dx,_dy,_w,_h,_dir) { \ DRAW_DEBUG ((DEBUG_RENDER, "blt %d,%d -> %d,%d %dx%d 0x%x", \ _sx,_sy,_dx,_dy,_w,_h,_dir)); \ - _s3CmdWait(s3); \ + _s3WaitSlots(s3,4); \ _s3SetCur(s3,_sx,_sy); \ _s3SetStep(s3,_dx,_dy); \ _s3SetPcnt(s3,(_w)-1,(_h)-1); \ @@ -235,6 +309,8 @@ void _s3LoadPattern (ScreenPtr pScreen, s3PatternPtr pPattern); #define _s3SetOpaquePlaneBlt(s3,alu,mask,_fg,_bg) {\ DRAW_DEBUG ((DEBUG_SET,"set opaque plane blt 0x%x 0x%x %d 0x%x", \ _fg, _bg, alu, mask)); \ + /* _s3WaitSlots(s3, 5); */ \ + _s3WaitIdleEmpty (s3); \ _s3SetFg(s3,_fg); \ _s3SetBg(s3,_bg); \ _s3SetWriteMask(s3,mask); \ @@ -246,6 +322,8 @@ void _s3LoadPattern (ScreenPtr pScreen, s3PatternPtr pPattern); #define _s3SetTransparentPlaneBlt(s3,alu,mask,_fg) {\ DRAW_DEBUG ((DEBUG_SET,"set transparent plane blt 0x%x %d 0x%x", \ _fg, alu, mask)); \ + /*_s3WaitSlots(s3, 4); */ \ + _s3WaitIdleEmpty (s3); \ _s3SetFg(s3,_fg); \ _s3SetWriteMask(s3,mask); \ _s3SetMix(s3,FSS_FRGDCOL|s3alu[alu], BSS_BKGDCOL|MIX_DST); \ @@ -256,7 +334,8 @@ void _s3LoadPattern (ScreenPtr pScreen, s3PatternPtr pPattern); /* Across the plane blt */ #define _s3PlaneBlt(s3,x,y,w,h) {\ DRAW_DEBUG ((DEBUG_RENDER, "plane blt %d,%d %dx%d", x,y,w,h)); \ - _s3CmdWait(s3); \ + _s3WaitSlots(s3, 4); \ + _s3SetPixelControl(s3,MIXSEL_EXPPC); \ _s3SetCur(s3, x, y); \ _s3SetPcnt (s3, (w)-1, (h)-1); \ _s3SetCmd (s3, \ @@ -274,7 +353,7 @@ void _s3LoadPattern (ScreenPtr pScreen, s3PatternPtr pPattern); #define _s3SetClip(s3,pbox) {\ DRAW_DEBUG ((DEBUG_SET, "set clip %dx%d -> %dx%d ", \ pbox->x1, pbox->y1, pbox->x2, pbox->y2)); \ - _s3WaitEmpty(s3); \ + _s3WaitSlots(s3, 2); \ _s3SetScissorsTl(s3,(pbox)->x1, (pbox)->y1); \ _s3SetScissorsBr(s3,(pbox)->x2 - 1, (pbox)->y2 - 1); \ DRAW_DEBUG((DEBUG_SET," done")); \ @@ -282,7 +361,7 @@ void _s3LoadPattern (ScreenPtr pScreen, s3PatternPtr pPattern); #define _s3ResetClip(s3,pScreen) { \ DRAW_DEBUG ((DEBUG_SET, "reset clip")); \ - _s3WaitEmpty(s3); \ + _s3WaitSlots(s3, 2); \ _s3SetScissorsTl(s3,0,0); \ _s3SetScissorsBr(s3,pScreen->width - 1, pScreen->height - 1); \ DRAW_DEBUG((DEBUG_SET," done")); \ @@ -298,6 +377,11 @@ s3CopyPlane(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC, int dstx, int dsty, unsigned long bitPlane); void +s3PushPixels (GCPtr pGC, PixmapPtr pBitmap, + DrawablePtr pDrawable, + int w, int h, int x, int y); + +void s3FillBoxSolid (DrawablePtr pDrawable, int nBox, BoxPtr pBox, unsigned long pixel, int alu, unsigned long planemask); @@ -369,4 +453,7 @@ s3CheckGCFill (GCPtr pGC); void s3MoveGCFill (GCPtr pGC); +void +s3SyncProc (DrawablePtr pDrawable); + #endif diff --git a/hw/kdrive/savage/s3gc.c b/hw/kdrive/savage/s3gc.c index 245dfc483..d62db68ae 100644 --- a/hw/kdrive/savage/s3gc.c +++ b/hw/kdrive/savage/s3gc.c @@ -22,7 +22,7 @@ * * Author: Keith Packard, SuSE, Inc. */ -/* $XFree86: $ */ +/* $XFree86: xc/programs/Xserver/hw/kdrive/savage/s3gc.c,v 1.1 1999/11/19 13:53:56 hohndel Exp $ */ #include "s3.h" #include "s3draw.h" @@ -48,17 +48,17 @@ */ /* TE font, >= 4 pixels wide, one clip rectangle */ -static GCOps s3TEOps1Rect = { +static const GCOps s3TEOps1Rect = { s3FillSpans, - fbSetSpans, - fbPutImage, + KdCheckSetSpans, + KdCheckPutImage, s3CopyArea, s3CopyPlane, - fbPolyPoint, + KdCheckPolyPoint, s3Polylines, s3PolySegment, miPolyRectangle, - fbPolyArc, + KdCheckPolyArc, s3FillPoly1Rect, s3PolyFillRect, s3PolyFillArcSolid, @@ -68,7 +68,7 @@ static GCOps s3TEOps1Rect = { miImageText16, s3ImageTEGlyphBlt, s3PolyTEGlyphBlt, - fbPushPixels, + s3PushPixels, #ifdef NEED_LINEHELPER ,NULL #endif @@ -77,17 +77,17 @@ static GCOps s3TEOps1Rect = { extern GCOps fbGCOps; /* Non TE font, one clip rectangle */ -static GCOps s3NonTEOps1Rect = { +static const GCOps s3NonTEOps1Rect = { s3FillSpans, - fbSetSpans, - fbPutImage, + KdCheckSetSpans, + KdCheckPutImage, s3CopyArea, s3CopyPlane, - fbPolyPoint, + KdCheckPolyPoint, s3Polylines, s3PolySegment, miPolyRectangle, - fbPolyArc, + KdCheckPolyArc, s3FillPoly1Rect, s3PolyFillRect, s3PolyFillArcSolid, @@ -97,24 +97,24 @@ static GCOps s3NonTEOps1Rect = { miImageText16, s3ImageGlyphBlt, s3PolyGlyphBlt, - fbPushPixels + s3PushPixels #ifdef NEED_LINEHELPER ,NULL #endif }; /* TE font, != 1 clip rect (including 0) */ -static GCOps s3TEOps = { +static const GCOps s3TEOps = { s3FillSpans, - fbSetSpans, - fbPutImage, + KdCheckSetSpans, + KdCheckPutImage, s3CopyArea, s3CopyPlane, - fbPolyPoint, + KdCheckPolyPoint, s3Polylines, s3PolySegment, miPolyRectangle, - fbPolyArc, + KdCheckPolyArc, miFillPolygon, s3PolyFillRect, s3PolyFillArcSolid, @@ -124,24 +124,24 @@ static GCOps s3TEOps = { miImageText16, s3ImageTEGlyphBlt, s3PolyTEGlyphBlt, - fbPushPixels + s3PushPixels #ifdef NEED_LINEHELPER ,NULL #endif }; /* Non TE font, != 1 clip rect (including 0) */ -static GCOps s3NonTEOps = { +static const GCOps s3NonTEOps = { s3FillSpans, - fbSetSpans, - fbPutImage, + KdCheckSetSpans, + KdCheckPutImage, s3CopyArea, s3CopyPlane, - fbPolyPoint, + KdCheckPolyPoint, s3Polylines, s3PolySegment, miPolyRectangle, - fbPolyArc, + KdCheckPolyArc, miFillPolygon, s3PolyFillRect, s3PolyFillArcSolid, @@ -151,7 +151,7 @@ static GCOps s3NonTEOps = { miImageText16, s3ImageGlyphBlt, s3PolyGlyphBlt, - fbPushPixels + s3PushPixels #ifdef NEED_LINEHELPER ,NULL #endif @@ -169,7 +169,7 @@ s3MatchCommon (DrawablePtr pDraw, GCPtr pGC, FbGCPrivPtr fbPriv) } if (pDraw->type != DRAWABLE_WINDOW) - return (GCOps *) &fbGCOps; + return (GCOps *) &kdAsyncPixmapGCOps; if (pGC->lineWidth != 0) return 0; @@ -184,16 +184,16 @@ s3MatchCommon (DrawablePtr pDraw, GCPtr pGC, FbGCPrivPtr fbPriv) if (TERMINALFONT(pGC->font)) { if (fbPriv->oneRect) - return &s3TEOps1Rect; + return (GCOps *) &s3TEOps1Rect; else - return &s3TEOps; + return (GCOps *) &s3TEOps; } else { if (fbPriv->oneRect) - return &s3NonTEOps1Rect; + return (GCOps *) &s3NonTEOps1Rect; else - return &s3NonTEOps; + return (GCOps *) &s3NonTEOps; } } return 0; @@ -283,7 +283,7 @@ s3ValidateGC (GCPtr pGC, Mask changes, DrawablePtr pDrawable) */ if (pGC->ops == &kdNoopOps) { - pGC->ops = (GCOps *) &fbGCOps; + pGC->ops = (GCOps *) &kdAsyncPixmapGCOps; new_type = TRUE; } pGC->ops = miCreateGCOps (pGC->ops); @@ -295,8 +295,8 @@ s3ValidateGC (GCPtr pGC, Mask changes, DrawablePtr pDrawable) */ if (new_type || (changes & (GCFillStyle|GCTile|GCStipple))) { - pGC->ops->FillSpans = fbFillSpans; - pGC->ops->PolyFillRect = fbPolyFillRect; + pGC->ops->FillSpans = KdCheckFillSpans; + pGC->ops->PolyFillRect = KdCheckPolyFillRect; if (s3Priv->type == DRAWABLE_WINDOW && (pGC->fillStyle != FillTiled || s3Priv->pPattern)) { @@ -310,13 +310,9 @@ s3ValidateGC (GCPtr pGC, Mask changes, DrawablePtr pDrawable) */ if (new_type) { - pGC->ops->CopyArea = fbCopyArea; - pGC->ops->CopyPlane = fbCopyPlane; - if (s3Priv->type == DRAWABLE_WINDOW) - { - pGC->ops->CopyArea = s3CopyArea; - pGC->ops->CopyPlane = s3CopyPlane; - } + pGC->ops->CopyArea = s3CopyArea; + pGC->ops->CopyPlane = s3CopyPlane; + pGC->ops->PushPixels = s3PushPixels; } /* @@ -324,8 +320,8 @@ s3ValidateGC (GCPtr pGC, Mask changes, DrawablePtr pDrawable) */ if (new_type || (changes & (GCLineStyle|GCLineWidth|GCFillStyle))) { - pGC->ops->Polylines = fbPolyLine; - pGC->ops->PolySegment = fbPolySegment; + pGC->ops->Polylines = KdCheckPolylines; + pGC->ops->PolySegment = miPolySegment; if (pGC->lineStyle == LineSolid && pGC->lineWidth == 0 && pGC->fillStyle == FillSolid && @@ -355,7 +351,7 @@ s3ValidateGC (GCPtr pGC, Mask changes, DrawablePtr pDrawable) */ if (new_type || (changes & GCFillStyle)) { - pGC->ops->PolyFillArc = fbPolyFillArc; + pGC->ops->PolyFillArc = miPolyFillArc; if (s3Priv->type == DRAWABLE_WINDOW && pGC->fillStyle == FillSolid) { @@ -368,8 +364,8 @@ s3ValidateGC (GCPtr pGC, Mask changes, DrawablePtr pDrawable) */ if (new_type || (changes & (GCFont|GCFillStyle))) { - pGC->ops->PolyGlyphBlt = fbPolyGlyphBlt; - pGC->ops->ImageGlyphBlt = fbImageGlyphBlt; + pGC->ops->PolyGlyphBlt = KdCheckPolyGlyphBlt; + pGC->ops->ImageGlyphBlt = KdCheckImageGlyphBlt; if (s3Priv->type == DRAWABLE_WINDOW && pGC->font) { if (pGC->fillStyle == FillSolid) diff --git a/hw/kdrive/savage/s3reg.c b/hw/kdrive/savage/s3reg.c index 38ca2e804..4f4ad85b8 100644 --- a/hw/kdrive/savage/s3reg.c +++ b/hw/kdrive/savage/s3reg.c @@ -22,7 +22,7 @@ * * Author: Keith Packard, SuSE, Inc. */ -/* $XFree86: $ */ +/* $XFree86: xc/programs/Xserver/hw/kdrive/savage/s3reg.c,v 1.1 1999/11/19 13:53:57 hohndel Exp $ */ #include "s3reg.h" @@ -360,6 +360,16 @@ VgaReg s3_v_blank_end[] = { VGA_REG_END }; +VgaReg s3_2bk_cga[] = { + CR17, 0, 1, + VGA_REG_END +}; + +VgaReg s3_4bk_hga[] = { + CR17, 1, 1, + VGA_REG_END +}; + VgaReg s3_v_total_double[] = { CR17, 2, 1, VGA_REG_END @@ -370,11 +380,21 @@ VgaReg s3_word_mode[] = { VGA_REG_END }; +VgaReg s3_address_16k_wrap[] = { + CR17, 5, 1, + VGA_REG_END +}; + VgaReg s3_byte_mode[] = { CR17, 6, 1, VGA_REG_END }; +VgaReg s3_hardware_reset[] = { + CR17, 7, 1, + VGA_REG_END +}; + VgaReg s3_line_compare[] = { CR18, 0, 8, CR07, 4, 1, @@ -414,6 +434,11 @@ VgaReg s3_border_select[] = { VGA_REG_END }; +VgaReg s3_lock_palette[] = { + CR33, 6, 1, + VGA_REG_END +}; + VgaReg s3_enable_sff[] = { CR34, 4, 1, VGA_REG_END @@ -639,6 +664,11 @@ VgaReg s3_color_mode[] = { VGA_REG_END }; +VgaReg s3_primary_stream_timeout[] = { + CR71, 0, 8, + VGA_REG_END +}; + VgaReg s3_master_control_unit_timeout[] = { CR74, 0, 8, VGA_REG_END @@ -674,6 +704,16 @@ VgaReg s3_fifo_fetch_timing[] = { VGA_REG_END }; +VgaReg s3_dac_power_up_time[] = { + CR86, 0, 7, + VGA_REG_END +}; + +VgaReg s3_dac_power_saving_disable[] = { + CR86, 7, 1, + VGA_REG_END +}; + VgaReg s3_primary_stream_l1[] = { CR91, 0, 8, CR90, 0, 3, @@ -985,7 +1025,22 @@ VgaReg s3_enable_blinking[] = { VGA_REG_END }; -#define AR_LAST AR10 +VgaReg s3_border_color[] = { + AR11, 0, 8, + VGA_REG_END +}; + +#define AR_LAST AR11 + +VgaReg s3_io_addr_select[] = { + S3_MISC_OUT, 0, 1, + VGA_REG_END +}; + +VgaReg s3_enable_ram[] = { + S3_MISC_OUT, 1, 1, + VGA_REG_END +}; VgaReg s3_clock_select[] = { S3_MISC_OUT, 2, 2, @@ -1002,13 +1057,43 @@ VgaReg s3_vert_sync_neg[] = { VGA_REG_END }; +VgaReg s3_display_mode_inactive[] = { + S3_INPUT_STATUS_1, 0, 1, + VGA_REG_END +}; + +VgaReg s3_vertical_sync_active[] = { + S3_INPUT_STATUS_1, 3, 1, + VGA_REG_END +}; + +VgaReg s3_dac_mask[] = { + S3_DAC + 0, 0, 8, + VGA_REG_END +}; + +VgaReg s3_dac_read_index[] = { + S3_DAC + 1, 0, 8, + VGA_REG_END +}; + +VgaReg s3_dac_write_index[] = { + S3_DAC + 2, 0, 8, + VGA_REG_END +}; + +VgaReg s3_dac_data[] = { + S3_DAC + 3, 0, 8, + VGA_REG_END +}; + VGA8 _s3Inb (VgaCard *card, VGA16 port) { VGAVOL8 *reg; if (card->closure) - return *(((VGAVOL8 *) card->closure) + port); + return VgaReadMemb ((VGA32) card->closure + port); else return VgaInb (port); } @@ -1016,10 +1101,8 @@ _s3Inb (VgaCard *card, VGA16 port) void _s3Outb (VgaCard *card, VGA8 value, VGA16 port) { - VGAVOL8 *reg; - if (card->closure) - *(((VGAVOL8 *) card->closure) + port) = value; + VgaWriteMemb (value, (VGA32) card->closure + port); else VgaOutb (value, port); } @@ -1050,14 +1133,19 @@ _s3RegMap (VgaCard *card, VGA16 reg, VgaMap *map, VGABOOL write) map->access = VgaAccessDone; /* reset AFF to index */ (void) _s3Inb (card, 0x3da); + if (reg >= 16) + reg |= 0x20; _s3Outb (card, reg, 0x3c0); if (write) _s3Outb (card, map->value, 0x3c0); else map->value = _s3Inb (card, 0x3c1); - /* enable video display again */ - (void) _s3Inb (card, 0x3da); - _s3Outb (card, 0x20, 0x3c0); + if (!(reg & 0x20)) + { + /* enable video display again */ + (void) _s3Inb (card, 0x3da); + _s3Outb (card, 0x20, 0x3c0); + } return; } else if (reg < S3_CR + S3_NCR) @@ -1068,6 +1156,11 @@ _s3RegMap (VgaCard *card, VGA16 reg, VgaMap *map, VGABOOL write) map->value = 1; map->index = reg - S3_CR; } + else if (reg < S3_DAC + S3_NDAC) + { + map->access = VgaAccessIo; + map->port = 0x3c6 + reg - S3_DAC; + } else switch (reg) { case S3_MISC_OUT: map->access = VgaAccessIo; @@ -1076,6 +1169,10 @@ _s3RegMap (VgaCard *card, VGA16 reg, VgaMap *map, VGABOOL write) else map->port = 0x3cc; break; + case S3_INPUT_STATUS_1: + map->access = VgaAccessIo; + map->port = 0x3da; + break; } if (card->closure) { @@ -1115,7 +1212,7 @@ s3Save (S3Vga *s3vga) s3vga->save_register_lock_1 = s3Get (s3vga, s3_register_lock_1); s3SetImm (s3vga, s3_register_lock_1, 0x48); s3vga->save_register_lock_2 = s3Get (s3vga, s3_register_lock_2); - s3SetImm (s3vga, s3_register_lock_2, 0xa0); + s3SetImm (s3vga, s3_register_lock_2, 0xa5); s3vga->save_unlock_extended_sequencer = s3Get (s3vga, s3_unlock_extended_sequencer); s3SetImm (s3vga, s3_unlock_extended_sequencer, 0x06); s3vga->save_lock_horz = s3Get (s3vga, s3_lock_horz); diff --git a/hw/kdrive/savage/s3reg.h b/hw/kdrive/savage/s3reg.h index f1ac18d03..6665de454 100644 --- a/hw/kdrive/savage/s3reg.h +++ b/hw/kdrive/savage/s3reg.h @@ -22,7 +22,7 @@ * * Author: Keith Packard, SuSE, Inc. */ -/* $XFree86: $ */ +/* $XFree86: xc/programs/Xserver/hw/kdrive/savage/s3reg.h,v 1.1 1999/11/19 13:53:57 hohndel Exp $ */ #ifndef _S3REG_H_ #define _S3REG_H_ @@ -37,8 +37,11 @@ #define S3_NAR 0x15 #define S3_CR (S3_AR+S3_NAR) #define S3_NCR 0xc0 -#define S3_MISC_OUT (S3_CR+S3_NCR) -#define S3_NREG (S3_MISC_OUT+1) +#define S3_DAC (S3_CR+S3_NCR) +#define S3_NDAC 4 +#define S3_MISC_OUT (S3_DAC + S3_NDAC) +#define S3_INPUT_STATUS_1 (S3_MISC_OUT+1) +#define S3_NREG (S3_INPUT_STATUS_1+1) extern VgaReg s3_h_total[]; extern VgaReg s3_h_display_end[]; @@ -63,9 +66,13 @@ extern VgaReg s3_count_by_4_mode[]; extern VgaReg s3_doubleword_mode[]; extern VgaReg s3_v_blank_start[]; extern VgaReg s3_v_blank_end[]; +extern VgaReg s3_2bk_cga[]; +extern VgaReg s3_4bk_hga[]; extern VgaReg s3_v_total_double[]; +extern VgaReg s3_address_16k_wrap[]; extern VgaReg s3_word_mode[]; extern VgaReg s3_byte_mode[]; +extern VgaReg s3_hardware_reset[]; extern VgaReg s3_line_compare[]; extern VgaReg s3_device_id[]; extern VgaReg s3_revision[]; @@ -74,6 +81,7 @@ extern VgaReg s3_enhanced_memory_mapping[]; extern VgaReg s3_enable_sff[]; extern VgaReg s3_lock_dac_writes[]; extern VgaReg s3_border_select[]; +extern VgaReg s3_lock_palette[]; extern VgaReg s3_lock_vert[]; extern VgaReg s3_lock_horz[]; extern VgaReg s3_io_disable[]; @@ -117,6 +125,7 @@ extern VgaReg s3_enable_2d_3d[]; extern VgaReg s3_pci_disconnect_enable[]; extern VgaReg s3_pci_retry_enable[]; extern VgaReg s3_color_mode[]; +extern VgaReg s3_primary_stream_timeout[]; extern VgaReg s3_master_control_unit_timeout[]; extern VgaReg s3_command_buffer_timeout[]; extern VgaReg s3_lpb_timeout[]; @@ -124,6 +133,8 @@ extern VgaReg s3_cpu_timeout[]; extern VgaReg s3_2d_graphics_engine_timeout[]; extern VgaReg s3_fifo_drain_delay[]; extern VgaReg s3_fifo_fetch_timing[]; +extern VgaReg s3_dac_power_up_time[]; +extern VgaReg s3_dac_power_saving_disable[]; extern VgaReg s3_primary_stream_l1[]; extern VgaReg s3_dot_clock_8[]; @@ -161,10 +172,22 @@ extern VgaReg s3_vga_dclk_m2[]; extern VgaReg s3_vga_clk_select[]; extern VgaReg s3_select_graphics_mode[]; extern VgaReg s3_enable_blinking[]; +extern VgaReg s3_border_color[]; + +extern VgaReg s3_io_addr_select[]; +extern VgaReg s3_enable_ram[]; extern VgaReg s3_clock_select[]; extern VgaReg s3_horz_sync_neg[]; extern VgaReg s3_vert_sync_neg[]; +extern VgaReg s3_display_mode_inactive[]; +extern VgaReg s3_vertical_sync_active[]; + +extern VgaReg s3_dac_mask[]; +extern VgaReg s3_dac_read_index[]; +extern VgaReg s3_dac_write_index[]; +extern VgaReg s3_dac_data[]; + #define s3Get(sv,r) VgaGet(&(sv)->card, (r)) #define s3GetImm(sv,r) VgaGetImm(&(sv)->card, (r)) #define s3Set(sv,r,v) VgaSet(&(sv)->card, (r), (v)) diff --git a/hw/kdrive/savage/s3stub.c b/hw/kdrive/savage/s3stub.c index 59e187984..31929976c 100644 --- a/hw/kdrive/savage/s3stub.c +++ b/hw/kdrive/savage/s3stub.c @@ -22,7 +22,7 @@ * * Author: Keith Packard, SuSE, Inc. */ -/* $XFree86: $ */ +/* $XFree86: xc/programs/Xserver/hw/kdrive/savage/s3stub.c,v 1.1 1999/11/19 13:53:57 hohndel Exp $ */ #include "s3.h" @@ -30,6 +30,13 @@ void InitCard (char *name) { KdCardAttr attr; +#ifdef VXWORKS + attr.naddr = 2; + attr.io = 0; + attr.address[0] = 0xbc000000; /* registers */ + attr.address[1] = 0xba000000; /* frame buffer */ + KdCardInfoAdd (&s3Funcs, &attr, 0); +#else CARD32 count; count = 0; @@ -38,6 +45,7 @@ InitCard (char *name) KdCardInfoAdd (&s3Funcs, &attr, 0); count++; } +#endif } void @@ -49,12 +57,31 @@ InitOutput (ScreenInfo *pScreenInfo, int argc, char **argv) void InitInput (int argc, char **argv) { +#ifdef VXWORKS + KdInitInput (&VxWorksMouseFuncs, &VxWorksKeyboardFuncs); +#endif +#ifdef linux KdInitInput (&Ps2MouseFuncs, &LinuxKeyboardFuncs); +#endif } -void -OsVendorInit (void) +extern int s3CpuTimeout; +extern int s3AccelTimeout; + +int +ddxProcessArgument (int argc, char **argv, int i) { - KdOsInit (&LinuxFuncs); + int ret; + + if (!strcmp (argv[i], "-cpu")) + { + s3CpuTimeout = strtol(argv[i+1], NULL, 0); + return 2; + } + if (!strcmp (argv[i], "-accel")) + { + s3AccelTimeout = strtol (argv[i+1], NULL, 0); + return 2; + } + return KdProcessArgument (argc, argv, i); } - |