⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 et4000.c

📁 linux 下svgalib编的一个界面程序示例
💻 C
📖 第 1 页 / 共 2 页
字号:
/* 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 *//* partially copyrighted (C) 1993 by Hartmut Schirmer *//* ET4000 code taken from VGAlib * ET4000 code modified to handle HiColor modes better by David Monro * Dynamic register loading by Hartmut Schirmer * HH: ET4000/W32 detection added and support for more than 1Mb (based on *     vgadoc3) (untested). * HH: Detect newer ET4000/W32p. *//* Note that the clock detection stuff is currently not used. *//* ET4000 registers description (from vgadoc2)   **   **   **   ** 102h: Microchannel Setup Control   ** bit 0  Disable Card if set   **   ** 3BFh (R/W): Hercules Compatability register   **    ** 3C0h index 16h: ATC Miscellaneous   **    (Write data to 3C0h, Read from 3C1h  (May not be needed))   ** bit 4,5  High resolution timings.   **       7  Bypass the internal palette if set   **   ** 3C3h (R/W): Microchannel Video Subsystem Enable Register:   ** bit 0  Enable Microchannel VGA if set   **   ** 3C4h index  6  (R/W): TS State Control   ** bit 1-2  dots per characters in text mode    **       (bit 0: 3c4 index 1, bit 0)   **       bit <2:0>   ! dots/char   **           111     !    16   **           100     !    12   **           011     !    11   **           010     !    10   **           001     !     8   **           000     !     9   **   ** 3C4h index  7  (R/W): TS Auxiliary Mode   ** bit 0  If set select MCLK/4 (if bit 6 is also set to 1)   **     1  If set select SCLK input from MCLK   **   3,5  Rom Bios Enable/Disable:   **     0 0  C000-C3FF Enabled   **     0 1  Rom disabled   **     1 0  C000-C5FF,C680-C7FF Enabled   **     1 1  C000-C7FF Enabled   **     6  MCLK/2 if set   **     7  VGA compatible if set EGA else.   **   ** 3CBh (R/W): PEL Address/Data Wd   **     ** 3CDh (R/W): Segment Select   **     0-3  64k Write bank nr (0..15)   **     4-7  64k Read bank nr (0..15)   **   ** 3CEh index  Dh (R/W): Microsequencer Mode   **   ** 3CEh index  Eh (R/W): Microsequencer Reset    **   ** 3d4h index 24h (R/W): Compatibility Control   ** bit 0  Enable Clock Translate   **     1  Additional Master Clock Select   **     2  Enable tri-state for all output pins   **     3  Enable input A8 of 1MB DRAMs   **     4  Reserved   **     5  Enable external ROM CRTC translation   **     6  Enable Double Scan and Underline Attribute   **     7  CGA/MDA/Hercules   **   ** 3d4h index 32h (R/W): RAS/CAS Video Config   **       Ram timing, System clock and Ram type. Sample values:   **      00h  VRAM  80nsec   **      09h  VRAM 100nsec   **      00h  VRAM  28MHz   **      08h  VRAM  36MHz   **      70h  DRAM  40MHz   **   ** 3d4h index 33h (R/W): Extended start ET4000    ** bit 0-1  Display start address bits 16-17   **     2-3  Cursor start address bits 16-17   **     Can be used to ID ET4000   **   ** 3d4h index 34h (R/W): Compatibility Control Register   ** bit 2  bit 3 of clock select (bit 1-0 in misc output)   **     3  if set Video Subsystem Enable Register at 46E8h   **             else at 3C3h.   **   ** 3d4h index 35h (R/W): Overflow High ET4000   ** bit 0  Vertical Blank Start Bit 10   **     1  Vertical Total Bit 10   **     2  Vertical Display End Bit 10   **     3  Vertical Sync Start Bit 10   **     4  Line Compare Bit 10   **     5  Gen-Lock Enabled if set (External sync)   **     6  Read/Modify/Write Enabled if set. Currently not implemented.   **     7  Vertical interlace if set   **   ** 3d4h index 36h (R/W): Video System Configuration 1   ** bit 0-2 Refresh count per line - 1   **     3   16 bit wide fonts if set, else 8 bit wide   **     4   Linear addressing if set. Video Memory is    **         mapped as a 1 Meg block above 1MB. (set   **      GDC index 6 bits 3,2 to zero (128k))   **     5   TLI addressing mode if set   **     6   16 bit data path (video memory) if set   **     7   16 bit data (I/O operations) if set   **   ** 3d4h index 37h (R/W): Video System Configuration 2   ** bit 0-1  Display memory data bus width   **          0,1=8bit, 2=16bit, 3=32bit; may be   **       read as number of memory banks (1,2,4)   **    2  Bus read data latch control. If set latches   **       databus at end of CAS cycle else one clock delay   **       3  Clear if 64kx4 RAMs                   ???   **     if set RAM size = (bit 0-1)*256k   **       else RAM size = (bit 0-1)* 64k   **       4  16 bit ROM access if set   **       5  Memory bandwidth (0 better than 1) ???   **       6  TLI internal test mode if set    **       7  VRAM installed if set DRAM else.   **   ** 3d4h index 3Fh (R/W):   ** bit   7  This bit seems to be bit 8 of the CRTC offset register (3d4h index 13h).   **   ** 3d8h (R/W): Display Mode Control   **   ** 46E8h (R):  Video Subsystem Enable Register   ** bit   3  Enable VGA if set   **   **   **       3C4h index 05 used.   **    **   **  Bank Switching:   **   **     64k banks are selected by the Segment Select Register at 3CDh.   **     Both a Read and a Write segment can be selected.   **   **  The sequence:    **   **      port[$3BF]:=3;   **      port[$3D8]:=$A0;   **   **  is apparently needed to enable the extensions in the Tseng 4000.   **   **   **  Used extended ET4000 registers (EXT+xx) :   **   **   00 : CRT (3d4) index 30   **   01 : CRT (3d4) index 31   **   02 : CRT (3d4) index 32   **   03 : CRT (3d4) index 33   **   04 : CRT (3d4) index 34   **   05 : CRT (3d4) index 35   **   06 : CRT (3d4) index 36   **   07 : CRT (3d4) index 37   **   08 : CRT (3d4) index 3f   **   09 : SEQ (3c4) index 07   **   0A : Microchannel register (3c3)   **   0B : Segment select (3cd)   **   0C : ATT (3c0) index 16   ** */#include <stdlib.h>#include <stdio.h>#include <unistd.h>#include <stdarg.h>#include <string.h>#include "vga.h"#include "libvga.h"#include "driver.h"#include "ramdac/ramdac.h"#define SEG_SELECT 0x3CD#define CHIP_ET4000	0	/* Chip types. */#define CHIP_ET4000W32	1#define CHIP_ET4000W32i	2#define CHIP_ET4000W32p	3static char *chipname[] ={    "ET4000",    "ET4000/W32",    "ET4000/W32i",    "ET4000/W32p"};static int et4000_memory;static int et4000_chiptype;static int et4000_init(int, int, int);static int et4000_interlaced(int mode);static void et4000_unlock(void);static void et4000_setlinear(int addr);static int et4000_extdac;static int pos_ext_settings, ext_settings;/* Mode table */#if defined(DYNAMIC)static ModeTable *et4000_modes = NULL;static ModeTable No_Modes = END_OF_MODE_TABLE;#else				/* !defined(DYNAMIC) */#include "et4000.regs"#ifdef DAC_TYPEstatic int et4000_dac = DAC_TYPE;#endifstatic ModeTable et4000_modes[] ={/* *INDENT-OFF* */    OneModeEntry(320x200x32K),    OneModeEntry(320x200x64K),    OneModeEntry(320x200x16M),    OneModeEntry(640x480x256),    OneModeEntry(640x480x32K),    OneModeEntry(640x480x64K),    OneModeEntry(640x480x16M),    OneModeEntry(800x600x16),    OneModeEntry(800x600x256),    OneModeEntry(800x600x32K),    OneModeEntry(800x600x64K),    OneModeEntry(1024x768x16),    OneModeEntry(1024x768x256),    OneModeEntry(1280x1024x16),    END_OF_MODE_TABLE/* *INDENT-ON* */};#endif				/* !defined(DYNAMIC) */#ifndef DAC_TYPEstatic int et4000_dac = -1;#endif/* Fill in chipset specific mode information */static void et4000_getmodeinfo(int mode, vga_modeinfo * modeinfo){    switch (modeinfo->colors) {    case 16:			/* 4-plane 16 color mode */	modeinfo->maxpixels = 65536 * 8;	break;    default:	if (modeinfo->bytesperpixel > 0)	    modeinfo->maxpixels = et4000_memory * 1024 /		modeinfo->bytesperpixel;	else	    modeinfo->maxpixels = et4000_memory * 1024;	break;    }    modeinfo->maxlogicalwidth = 4088;    modeinfo->startaddressrange = 0xfffff;    if (mode == G320x200x256)	modeinfo->startaddressrange = 0;    modeinfo->haveblit = 0;    modeinfo->memory = et4000_memory * 1024;    modeinfo->flags |= HAVE_RWPAGE | HAVE_EXT_SET;    if (et4000_interlaced(mode))	modeinfo->flags |= IS_INTERLACED;    if (et4000_chiptype != CHIP_ET4000)	modeinfo->flags |= EXT_INFO_AVAILABLE | CAPABLE_LINEAR;}/* ----------------------------------------------------------------- *//* Set/get the actual clock frequency */#if defined(USE_CLOCKS) || defined(DYNAMIC)#ifndef CLOCKS#define CLOCKS 24#endif#ifndef CLOCK_VALUES#define CLOCK_VALUES { 0 }#endifstatic unsigned clocks[CLOCKS] = CLOCK_VALUES;#endif#ifdef USE_CLOCKS/* Only include the rest of the clock stuff if USE_CLOCKS is defined. */static int et4000_clocks(int clk){    unsigned char temp;    int res;    /* get actual clock */    res = (inb(MIS_R) >> 2) & 3;	/* bit 0..1 */    outb(__svgalib_CRT_I, 0x34);    res |= (inb(__svgalib_CRT_D) & 2) << 1;	/* bit 2 */    outb(SEQ_I, 0x07);    temp = inb(SEQ_D);    if (temp & 0x41 == 0x41)	res |= 0x10;		/* bit 3..4 */    else	res |= (temp & 0x40) >> 3;	/* bit 3 */    if (clk >= CLOCKS)	clk = CLOCKS - 1;    if (clk >= 0) {	/* Set clock */	temp = inb(MIS_R) & 0xF3;	outb(MIS_W, temp | ((clk & 3) << 2));	outb(__svgalib_CRT_I, 0x34);	temp = inb(__svgalib_CRT_D) & 0xFD;	outb(__svgalib_CRT_D, temp | ((clk & 4) >> 1));	outb(SEQ_I, 0x07);	temp = inb(SEQ_D) & 0xBE;	temp |= (clk & 0x10 ? 0x41 : 0x00);	temp |= (clk & 0x08) << 3;	outb(SEQ_D, temp);	usleep(5000);    }    return res;}#define FRAMES 2/* I think the Xfree86 uses a similar BAD HACK ... */static int measure(int frames){    unsigned counter;    __asm__ volatile (			 "	xorl	%0,%0		\n"			 "__W1:	inb	%1,%%al		\n"			 "	testb	$8,%%al		\n"			 "	jne	__W1		\n"			 "__W2:	inb	%1,%%al		\n"			 "	testb	$8,%%al		\n"			 "	je	__W2		\n"			 "__L1:	inb	%1,%%al		\n"			 "	incl	%0		\n"			 "	testb	$8,%%al		\n"			 "	jne	__L1		\n"			 "__L2:	inb	%1,%%al		\n"			 "	incl	%0		\n"			 "	testb	$8,%%al		\n"			 "	je	__L2		\n"			 "__L3:	decl	%2		\n"			 "	jns	__L1		\n"			 :"=b" (counter)			 :"d"((unsigned short) (0x3da)), "c"(frames)			 :"ax", "cx"    );    return counter;}#define BASIS_FREQUENCY 28322static int measure_clk(int clk){    unsigned new;    int old_clk, state;    static unsigned act = 0;    old_clk = et4000_clocks(-1);    if ((state = SCREENON))	vga_screenoff();    if (act == 0) {	unsigned char save = inb(MIS_R);	outb(MIS_W, (save & 0xF3) | 0x04);	act = measure(FRAMES);	outb(MIS_W, save);    }    et4000_clocks(clk);    new = measure(FRAMES);    et4000_clocks(old_clk);    if (state)	vga_screenon();    return (((long long) BASIS_FREQUENCY) * act) / new;}#define set1(f,v) ({ if ((f)==0) (f)=(v); })static void set3(unsigned *f, int clk, unsigned base){    if (clk - 16 >= 0)	set1(f[clk - 16], 4 * base);    if (clk - 8 >= 0)	set1(f[clk - 8], 2 * base);    set1(f[clk], base);    if (clk + 8 < CLOCKS)	set1(f[clk + 8], base / 2);    if (clk + 16 < CLOCKS)	set1(f[clk + 16], base / 4);}static int get_clock(int clk){    static int first = 1;    if (clk < 0 || clk >= CLOCKS)	return 0;    if (first) {	int act_clk;	first = 0;	act_clk = et4000_clocks(-1);	act_clk &= 0xFC;	set3(clocks, act_clk, 25175);	/* act_clk  : 25175 KHz */	set3(clocks, act_clk + 1, 28322);	/* act_clk+1: 28322 KHz */	for (act_clk = 0; act_clk < CLOCKS; ++act_clk)	    if (clocks[act_clk] != 0)		set3(clocks, act_clk, clocks[act_clk]);    }    if (clocks[clk] == 0) {	int c = clk & 7;	clocks[16 + c] = measure_clk(16 + c);	clocks[8 + c] = 2 * clocks[16 + c];	clocks[c] = 2 * clocks[8 + c];    }    return clocks[clk];}#endif				/* defined(USE_CLOCKS) *//* ----------------------------------------------------------------- *//* Read and store chipset-specific registers */static int et4000_saveregs(unsigned char regs[]){    int i;    et4000_unlock();    /* save extended CRT registers */    for (i = 0; i < 8; i++) {	port_out(0x30 + i, __svgalib_CRT_I);	regs[EXT + i] = port_in(__svgalib_CRT_D);    }    port_out(0x3f, __svgalib_CRT_I);    regs[EXT + 8] = port_in(__svgalib_CRT_D);    /* save extended sequencer register */    port_out(7, SEQ_I);    regs[EXT + 9] = port_in(SEQ_D);    /* save some other ET4000 specific registers */    regs[EXT + 10] = port_in(0x3c3);    regs[EXT + 11] = port_in(0x3cd);    /* save extended attribute register */    port_in(__svgalib_IS1_R);		/* reset flip flop */    port_out(0x16, ATT_IW);    regs[EXT + 12] = port_in(ATT_R);    if (et4000_extdac) {	_ramdac_dactocomm();	regs[EXT + 13] = inb(PEL_MSK);	_ramdac_dactocomm();	outb(PEL_MSK, regs[EXT + 13] | 0x10);	_ramdac_dactocomm();	inb(PEL_MSK);	outb(PEL_MSK, 3);		/* write index low */	outb(PEL_MSK, 0);		/* write index high */	regs[EXT + 14] = inb(PEL_MSK);	/* primary ext. pixel select */	regs[EXT + 15] = inb(PEL_MSK);	/* secondary ext. pixel select */	regs[EXT + 16] = inb(PEL_MSK);	/* PLL control register */	_ramdac_dactocomm();	outb(PEL_MSK, regs[EXT + 13]);	return 17;    }    return 13;			/* ET4000 requires 13 additional registers */}/* Set chipset-specific registers */static void et4000_setregs(const unsigned char regs[], int mode){    int i;    unsigned char save;    /* make sure linear mode is forced off */    et4000_setlinear(0);    et4000_unlock();    /* write some ET4000 specific registers */    port_out(regs[EXT + 10], 0x3c3);    port_out(regs[EXT + 11], 0x3cd);    /* write extended sequencer register */    port_out(7, SEQ_I);    port_out(regs[EXT + 9], SEQ_D);#if 0				/* This writes to registers we shouldn't write to. */    /* write extended CRT registers */    for (i = 0; i < 6; i++) {	port_out(0x32 + i, __svgalib_CRT_I);	port_out(regs[EXT + i], __svgalib_CRT_D);    }    port_out(0x3f, __svgalib_CRT_I);    port_out(regs[EXT + 6], __svgalib_CRT_D);#endif    /* deprotect CRT register 0x35 */    port_out(0x11, __svgalib_CRT_I);    save = port_in(__svgalib_CRT_D);    port_out(save & 0x7F, __svgalib_CRT_D);    /* write extended CRT registers */    for (i = 0; i < 6; i++) {	port_out(0x30 + i, __svgalib_CRT_I);	port_out(regs[EXT + i], __svgalib_CRT_D);    }    port_out(0x36, __svgalib_CRT_I);    port_out((port_in(__svgalib_CRT_D) & 0x40) | (regs[EXT + 6] & 0xbf), __svgalib_CRT_D);    port_out(0x37, __svgalib_CRT_I);    port_out((port_in(__svgalib_CRT_D) & 0xbb) | (regs[EXT + 7] & 0x44), __svgalib_CRT_D);    port_out(0x3f, __svgalib_CRT_I);    port_out(regs[EXT + 8], __svgalib_CRT_D);    /* set original CRTC 0x11 */    port_out(0x11, __svgalib_CRT_I);    port_out(save, __svgalib_CRT_D);    /* write extended attribute register */    port_in(__svgalib_IS1_R);		/* reset flip flop */    port_out(0x16, ATT_IW);    port_out(regs[EXT + 12], ATT_IW);    if (et4000_extdac) {	_ramdac_dactocomm();	outb(PEL_MSK, regs[EXT + 13] | 0x10);	_ramdac_dactocomm();	inb(PEL_MSK);	outb(PEL_MSK, 3);		/* write index low */	outb(PEL_MSK, 0);		/* write index high */	outb(PEL_MSK, regs[EXT + 14]);	/* primary ext. pixel select */	outb(PEL_MSK, regs[EXT + 15]);	/* secondary ext. pixel select */	outb(PEL_MSK, regs[EXT + 16]);	/* PLL control register */	_ramdac_dactocomm();	outb(PEL_MSK, regs[EXT + 13]);    }}/* Return non-zero if mode is available */static int et4000_modeavailable(int mode){    const unsigned char *regs;    struct info *info;    regs = LOOKUPMODE(et4000_modes, mode);    if (regs == NULL || mode == GPLANE16)	return __svgalib_vga_driverspecs.modeavailable(mode);    if (regs == DISABLE_MODE || mode <= TEXT || mode > GLASTMODE)	return 0;    info = &__svgalib_infotable[mode];    if (et4000_memory * 1024 < info->ydim * info->xbytes)	return 0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -