📄 s3.c
字号:
/* * VGAlib version 1.2 - (c) 1993 Tommy Frandsen * * This library is free software; you can redistribute it and/or * modify it without any restrictions. This library is distributed * in the hope that it will be useful, but without any warranty. * * Multi-chipset support Copyright (C) 1993 Harm Hanemaayer * S3 805,868 support Copyright (C) 1995 Stephen Lee *//* * Mar 1999 (Eduardo ...) * Recognizes Trio3D as Trio64 * * Sep 1997 (Greg Alexander): * Recognizes S3Trio64V2/DX cards as Trio64's. * * Feb 1996 (Stephen Lee): * 968/IBMRGB support. Only 256 colors for now. * can now save more than 10 DAC registers (IBMRGB has 256!) * Trio64 patch from Moto Kawamura <kawamura@mmp.cl.nec.co.jp>. * Changed handling of CR34 for VGA modes at Andreas' suggestion. * Changes to s3_saveregs() and s3_setregs() to make them more safe against * lockups. * 16 color mode should work on the 868/SDAC. * SDAC 4/8bpp doesn't seem to do pixel multiplexing. * * Dec 1995 (Stephen Lee): * Fixed color problem with 868 (CR43 again!). Could somebody find the * value that works with Trio64? * * Nov 1995 (Stephen Lee): * Linear addressing mode partially works (but is very alpha). * Merged in Andreas Arens' <ari@av.rwth-aachen.de> patch for the 928. * * Sep 1995 (Stephen Lee): * 16 Colors works on my 805, should work on other cards too. * * Alternate banking scheme for 864+. If you have problems, try undefining * S3_LINEAR_MODE_BANKING_864. * * 8 bit color *really* works. Took me 3 months to bag this sucker. * * SVGA 8 bit color modes works. 320x200x256 is not really 'packed-pixel', * it occupies 256K per page. There is no SVGA 320x200x256 mode; I cannot * get the display (timing?) right. * * Aug 1995 (Stephen Lee): * Added "Dacspeed" parsing. * Added support for CLUT8_8 on ATT20C490/498. * Improved support for S3-801/805. * 15/16/24 bit colors works on the 805 + ATT20C490 I tested. * Newer chipsets are recognized (but no support coded in yet). * Should recognize memory size correctly on S3-924. * * Dec 1994 (Harm Hanemaayer): * Partially rewritten using new SVGA-abstracted interface. * Based on XFree86 code (accel/s3/s3.c and s3init.c). * Goal is to have support for the S3-864 + S3-SDAC (which I can test). * 80x with GENDAC might also be supported. * Also, 640x480x256 should work on cards that have standard 25 and 28 MHz * clocks. * * XFree86-equivalent clock select is now supported plus some * industry-standard RAMDACs. * * Remaining problems: * * Okay, okay, so 256 color still isn't fully working on the 805. I'm * trying to get a fix for it. * * * The DCLK limit for 864/868 is a bit too relaxed. If you see noise at * the highest resolutions when the screen is drawing it is possibly due * to this. (How about changing MCLK?) * * * Horizontal Total is limited to 4088 which makes some modes unavailable * (e.g. 800x600x16M with HTotal > 1022). Should experiment with * CR43.7? * * * Some 864 problems are now fixed -- XF86_S3 seems to program the * linewidth in bytes doubled for the S3-864 with > 1024K, which * caused problems for this driver. There's still interference * though when writing to video memory in the higher resolutions. * * * XXXX results of malloc() are not checked: should fix sometime. */#include <stdlib.h>#include <stdarg.h>#include <stdio.h>#include <string.h>#include <unistd.h> /* iopl() */#include "vga.h"#include "libvga.h"#include "driver.h"#include "timing.h"#include "ramdac/ramdac.h"#include "clockchip/clockchip.h"#include "vgaregs.h"#include "interface.h"#include "8514a.h"#include "vgapci.h"/* no acceleration as of now. */#undef S3_USE_GRAPHIC_ENGINE/* kludge packed pixel for 320x200x256 *//* XXXX doesn't really work */#undef S3_KLUDGE_PAGE_MODE/* use alternate 'linear' banking method for 864+ */#undef S3_LINEAR_MODE_BANKING_864#ifdef __alpha__ /* no good for alpha's */#undef S3_LINEAR_MODE_BANKING_864#endif/* * supports linear buffer. * * XXXX does not work with console switching and might be incompatible with * S3_LINEAR_MODE_BANKING_864. */#define S3_LINEAR_SUPPORT/* supports 16 colors */#define S3_16_COLORS/* * zero wait state + (ramdac?) FIFO for 864 & 805, * twice as fast but might not work on some cards. */#undef S3_0_WAIT_805_864enum { S3_911, S3_924, S3_801, S3_805, S3_928, S3_864, S3_964, S3_TRIO32, S3_TRIO64, S3_866, S3_868, S3_968, S3_765};static const char *s3_chipname[] ={"911", "924", "801", "805", "928", "864", "964", "Trio32", "Trio64", "866", "868", "968", "Trio64V+"};#define S3_CR(n) (EXT + (0x##n) - 0x30)#define S3_CR30 S3_CR(30)#define S3_CR31 S3_CR(31)#define S3_CR32 S3_CR(32)#define S3_CR33 S3_CR(33)#define S3_CR34 S3_CR(34)#define S3_CR35 S3_CR(35)#define S3_CR3A S3_CR(3A)#define S3_CR3B S3_CR(3B)#define S3_CR3C S3_CR(3C)#define S3_CR40 S3_CR(40)#define S3_CR42 S3_CR(42)#define S3_CR43 S3_CR(43)#define S3_CR44 S3_CR(44)#define S3_CR50 S3_CR(50) /* 801+ */#define S3_CR51 S3_CR(51)#define S3_CR53 S3_CR(53)#define S3_CR54 S3_CR(54)#define S3_CR55 S3_CR(55)#define S3_CR58 S3_CR(58)#define S3_CR59 S3_CR(59)#define S3_CR5A S3_CR(5A)#define S3_CR5D S3_CR(5D)#define S3_CR5E S3_CR(5E)#define S3_CR60 S3_CR(60)#define S3_CR61 S3_CR(61)#define S3_CR62 S3_CR(62)#define S3_CR67 S3_CR(67)#define S3_CR6A S3_CR(6A)#define S3_CR6D S3_CR(6D)/* For debugging, these (non-)registers are read also (but never written). */#define S3_CR36 S3_CR(36)#define S3_CR37 S3_CR(37)#define S3_CR38 S3_CR(38)#define S3_CR39 S3_CR(39)#define S3_CR3D S3_CR(3D)#define S3_CR3E S3_CR(3E)#define S3_CR3F S3_CR(3F)#define S3_CR45 S3_CR(45)#define S3_CR46 S3_CR(46)#define S3_CR47 S3_CR(47)#define S3_CR48 S3_CR(48)#define S3_CR49 S3_CR(49)#define S3_CR4A S3_CR(4A)#define S3_CR4B S3_CR(4B)#define S3_CR4C S3_CR(4C)#define S3_CR4D S3_CR(4D)#define S3_CR4E S3_CR(4E)#define S3_CR4F S3_CR(4F)#define S3_CR52 S3_CR(52)#define S3_CR56 S3_CR(56)#define S3_CR57 S3_CR(57)#define S3_CR5B S3_CR(5B)#define S3_CR5C S3_CR(5C)#define S3_CR5F S3_CR(5F)#define S3_CR63 S3_CR(63)#define S3_CR64 S3_CR(64)#define S3_CR65 S3_CR(65)#define S3_CR66 S3_CR(66)#define S3_CR6E S3_CR(6E)#define S3_CR6F S3_CR(6F)/* Trio extended SR registers */#define S3_SR(n) (S3_CR6F + 1 + (0x##n) - 0x08)#define S3_SR08 S3_SR(08)#define S3_SR09 S3_SR(09)#define S3_SR0A S3_SR(0A)#define S3_SR0D S3_SR(0D)#define S3_SR10 S3_SR(10)#define S3_SR11 S3_SR(11)#define S3_SR12 S3_SR(12)#define S3_SR13 S3_SR(13)#define S3_SR15 S3_SR(15)#define S3_SR18 S3_SR(18)#define S3_SR1D S3_SR(1D)#define S3_8514_OFFSET (S3_SR1D + 1)#define S3_8514_COUNT (1) /* number of 2-byte words */#define S3_DAC_OFFSET (S3_8514_OFFSET + (S3_8514_COUNT * 2))#define S3_TOTAL_REGS (S3_DAC_OFFSET + MAX_DAC_STATE)/* 8514 regs */#define S3_ADVFUNC_CNTL 0static unsigned short s3_8514regs[S3_8514_COUNT] ={ /* default assuming text mode */ 0x0000U};/* flags used by this driver */#define S3_LOCALBUS 0x01#define S3_CLUT8_8 0x02#define S3_OLD_STEPPING 0x04static int s3_flags = 0;static int s3_chiptype;static int s3_memory;static CardSpecs *cardspecs;static DacMethods *dac_used;static ClockChipMethods *clk_used;static int dac_speed = 0;int s3Mclk = 0;/* forward declaration. */extern DriverSpecs __svgalib_s3_driverspecs;static int s3_init(int, int, int);static void s3_setpage(int page);#ifdef S3_LINEAR_MODE_BANKING_864static void s3_setpage864(int page);#endif#ifdef S3_LINEAR_SUPPORTstatic int s3_cr40;static int s3_cr54;static int s3_cr58;static int s3_cr59;static int s3_cr5A;static int s3_linear_opt = 0;static int s3_linear_addr = 0;static int s3_linear_base = 0;static void s3_linear_enable(void);static void s3_linear_disable(void);#endifstatic void nothing(void){}/* * Lock S3's registers. * There are more locks, but this should suffice. * * ARI: More complete Extended VGA Register Lock Documentation, as of Ferraro: * * Register Bit Controls Access To: Function * CR33 1 CR7 bits 1 and 6 1=disable write protect * setting of CR11 bit 7 * CR33 4 Ramdac Register 1=disable writes * CR33 6 Palette/Overscan Registers 1=lock * CR34 5 Memory Configuration bit 5 1=lock * CR34 7 Misc Register bit 3-2 (Clock) 1=lock * CR35 4 Vertical Timing Registers 1=lock * CR35 5 Horizontal Timing Registers 1=lock * * XXXX mostly, need to lock the enhanced command regs on the 805 (and * probably below) to avoid display corruption. */static void s3_lock(void){ __svgalib_outCR(0x39, 0x00); /* Lock system control regs. */ __svgalib_outCR(0x38, 0x00); /* Lock special regs. */}static void s3_lock_enh(void){ if (s3_chiptype > S3_911) __svgalib_outCR(0x40, __svgalib_inCR(0x40) & ~0x01); /* Lock enhanced command regs. */ s3_lock();}/* * Unlock S3's registers. * There are more locks, but this should suffice. */static void s3_unlock(void){ __svgalib_outCR(0x38, 0x48); /* Unlock special regs. */ __svgalib_outCR(0x39, 0xA5); /* Unlock system control regs. */}static void s3_unlock_enh(void){ s3_unlock(); if (s3_chiptype > S3_911) __svgalib_outCR(0x40, __svgalib_inCR(0x40) | 0x01); /* Unlock enhanced command regs. */}/* * Adjust the display width. This is necessary for the graphics * engine if acceleration is used. However it will require more * memory making some modes unavailable. */static int s3_adjlinewidth(int oldwidth){ if (s3_chiptype < S3_801) return 1024;#ifdef S3_USE_GRAPHIC_ENGINE if (oldwidth <= 640) return 640; if (oldwidth <= 800) return 800; if (oldwidth <= 1024) return 1024; if (!(s3_flags & S3_OLD_STEPPING)) if (oldwidth <= 1152) return 1152; if (oldwidth <= 1280) return 1280; if (oldwidth <= 1600 && s3_chiptype >= S3_864) return 1600; return 2048;#else return oldwidth;#endif}/* Fill in chipset specific mode information */static void s3_getmodeinfo(int mode, vga_modeinfo * modeinfo){ switch (modeinfo->colors) { case 16: /* 4-plane 16 color mode */ modeinfo->maxpixels = s3_memory * 1024 * 2; break; default: modeinfo->maxpixels = s3_memory * 1024 / modeinfo->bytesperpixel; } /* Adjust line width (only for SVGA modes) */ if (!(mode < G640x480x256 || mode == G720x348x2)) modeinfo->linewidth = s3_adjlinewidth(modeinfo->linewidth); modeinfo->maxlogicalwidth = 8184; if (s3_chiptype >= S3_801) modeinfo->startaddressrange = 0x3fffff; else modeinfo->startaddressrange = 0xfffff;#ifdef S3_KLUDGE_PAGE_MODE if (mode == G320x200x256) { /* set page size to 256k. */ modeinfo->startaddressrange /= 4; modeinfo->maxpixels /= 4; }#else if (mode == G320x200x256) { /* disable page flipping. */ /* modeinfo->startaddressrange = 0xffff; */ modeinfo->startaddressrange = 0; modeinfo->maxpixels = 65536; }#endif modeinfo->haveblit = 0; modeinfo->flags &= ~HAVE_RWPAGE; modeinfo->flags |= HAVE_EXT_SET;#ifdef S3_LINEAR_SUPPORT if (modeinfo->bytesperpixel >= 1) { modeinfo->flags |= CAPABLE_LINEAR; if (s3_linear_addr) modeinfo->flags |= IS_LINEAR; }#endif modeinfo->memory = s3_memory; modeinfo->chiptype = s3_chiptype;}/* * XXX Part of this function should be implemented in ramdac.c, * but we just kludge it here for now. */static int s3_ext_set(unsigned what, va_list params){ int param2, old_values; unsigned char regs[10]; /* only know this, for now */ if (dac_used->id != ATT20C490 && dac_used->id != ATT20C498 && dac_used->id != SIERRA_15025) return 0; param2 = va_arg(params, int); old_values = (s3_flags & S3_CLUT8_8) ? VGA_CLUT8 : 0; switch (what) { case VGA_EXT_AVAILABLE: switch (param2) { case VGA_AVAIL_SET: return VGA_EXT_AVAILABLE | VGA_EXT_SET | VGA_EXT_CLEAR | VGA_EXT_RESET; case VGA_AVAIL_ACCEL: return 0; case VGA_AVAIL_FLAGS: return VGA_CLUT8; } break; case VGA_EXT_SET: if (param2 & VGA_CLUT8) goto setclut8; case VGA_EXT_CLEAR: if (param2 & VGA_CLUT8) goto clearclut8; case VGA_EXT_RESET: if (param2 & VGA_CLUT8) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -