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

📄 ali.c

📁 linux 下svgalib编的一个界面程序示例
💻 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 1993 Harm Hanemaayer * partially copyrighted (C) 1993 by Hartmut Schirmer * * ALI2301 driver release 2.0 released 1996 by Ron Koerner * (koerne00@marvin.informatik.uni-dortmund.de) * * initialization stuff is based on X server routines * lots of information were from VGADOC4b.ZIP by Finn Thoegersen * (very good source for (S)VGA-hardware-related stuff) * * * Features in this release: * * all modes, that is * * XxYxC mode * * with (X,Y) from {(320,200),(640,480),(800,600),(1024,768),(1280,1024)} * * and C from {256,32K,64K,16M} (no(!) 16-color modes, sorry) * * well, umm, that is, the mode is only available, if it fits in 1MB :) * * * * and even more, which do not fit into SVGALIBs pattern * * actually all modes supported by UNIVBE 5.1 (at least I hope) * * Todo: * * add 16 color modes * * add accelerator functions * */#include <stdio.h>#include <string.h>#include "vga.h"#include "libvga.h"#include "driver.h"#include <sys/mman.h>#include "ali.regs"static int ali_memory;static unsigned char last_page = 0;static int ali_init(int, int, int);static int ali_memorydetect(void);static int GETB(int, int);static void ali_unlock(void);static void ali_setpage(int page);static void SETB(int, int, int);/* Mode table */static ModeTable ali_modes[] ={/* *INDENT-OFF* */    OneModeEntry(640x480x256),    OneModeEntry(800x600x256),    OneModeEntry(1024x768x256),    OneModeEntry(640x480x64K),    OneModeEntry(640x480x16M),    OneModeEntry(800x600x64K),    OneModeEntry(320x200x32K),    OneModeEntry(320x200x64K),    OneModeEntry(320x200x16M),    OneModeEntry(640x480x32K),    OneModeEntry(640x480x64K),    OneModeEntry(640x480x16M),    OneModeEntry(800x600x32K),    OneModeEntry(800x600x64K),/*   OneModeEntry(800x600x16M), *//*   OneModeEntry(1024x768x32K), *//*   OneModeEntry(1024x768x64K), *//*   OneModeEntry(1024x768x16M), *//*   OneModeEntry(800x600x16), *//*   OneModeEntry(1024x768x16), *//*   OneModeEntry(1280x1024x16), */    END_OF_MODE_TABLE/* *INDENT-ON* */};/* ali_getmodeinfo( int mode, vga_modeinfo *modeinfo)   Tell SVGALIB stuff * Return mode information (blityes/no, start address, interlace, linear */static void ali_getmodeinfo(int mode, vga_modeinfo * modeinfo){    if (modeinfo->bytesperpixel > 0) {	modeinfo->maxpixels = ali_memory * 1024 / modeinfo->bytesperpixel;    } else {	modeinfo->maxpixels = ali_memory * 1024;	/* any val */    }    if (modeinfo->height)	modeinfo->maxlogicalwidth = ali_memory * 1024 / modeinfo->height;    else	modeinfo->maxlogicalwidth = 2048;    modeinfo->startaddressrange = 0xfffff;    switch (mode) {    case G320x200x256:	modeinfo->maxpixels = 65535;	modeinfo->maxlogicalwidth = 320;	modeinfo->startaddressrange = 0x0;	break;    case G640x480x16M:	modeinfo->linewidth = 2048;	break;    }    modeinfo->haveblit = 0;    modeinfo->flags |= HAVE_RWPAGE;}/* ali_saveregs( unsigned char regs[] )                 Save extended regs * Save extended registers into regs[]. */static int ali_saveregs(unsigned char regs[]){    int tmp;    ali_unlock();    tmp = GETB(GRA_I, 0x0c);    regs[EXT + 7] = inb(0x3d6);    regs[EXT + 8] = inb(0x3d7);    outb(0x3d6, 0);    regs[EXT + 0] = GETB(__svgalib_CRT_I, 0x19);    regs[EXT + 1] = GETB(__svgalib_CRT_I, 0x1a);    regs[EXT + 2] = GETB(__svgalib_CRT_I, 0x28);    regs[EXT + 3] = GETB(__svgalib_CRT_I, 0x2a);    regs[EXT + 4] = GETB(GRA_I, 0x0b);    regs[EXT + 5] = tmp;    inb(0x3c8);    inb(0x3c6);    inb(0x3c6);    inb(0x3c6);    inb(0x3c6);    regs[EXT + 6] = inb(0x3c6);    return 9;			/* 9 additional registers */}/* ali_setregs( unsigned char regs[], int mode )         * Set extended registers for specified graphics mode */static void ali_setregs(const unsigned char regs[], int mode){    int tmp;    ali_unlock();    tmp = GETB(GRA_I, 0x0f);    outb(GRA_D, tmp | 4);    outb(0x3d6, 0);    outb(0x3d7, 0);    SETB(__svgalib_CRT_I, 0x19, regs[EXT + 0]);    SETB(__svgalib_CRT_I, 0x1a, regs[EXT + 1] | 0x10);	/* |0x10 to prevent locking */    SETB(GRA_I, 0x0b, regs[EXT + 4]);    SETB(GRA_I, 0x0c, regs[EXT + 5]);    SETB(__svgalib_CRT_I, 0x28, regs[EXT + 2]);    SETB(__svgalib_CRT_I, 0x2a, regs[EXT + 3]);    inb(0x3c8);    inb(0x3c6);    inb(0x3c6);    inb(0x3c6);    inb(0x3c6);    outb(0x3c6, regs[EXT + 6]);    outb(0x3d6, regs[EXT + 7]);    outb(0x3d7, regs[EXT + 8]);}/* ali_modeavailable( int mode )                        Check if mode supported * Verify that desired graphics mode can be displayed by chip/memory combo * Returns SVGADRV flag if SVGA, vga_chipsetfunctions if VGA, 0 otherwise */static int ali_modeavailable(int mode){    const unsigned char *regs;    struct info *info;    regs = LOOKUPMODE(ali_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 (ali_memory * 1024 < info->ydim * info->xbytes) {	return 0;    }    return SVGADRV;}/* ali_setmode( int mode, int prv_mode )                Set graphics mode * Attempts to set a graphics mode. * Returns 0 if successful, 1 if unsuccessful *  * Calls vga_chipsetfunctions if VGA mode) */static int ali_setmode(int mode, int prv_mode){    const unsigned char *rp;    unsigned char regs[sizeof(g640x480x256_regs)];    rp = LOOKUPMODE(ali_modes, mode);    if (rp == NULL || mode == GPLANE16)	return (int) (__svgalib_vga_driverspecs.setmode(mode, prv_mode));    if (!ali_modeavailable(mode))	return 1;		/* mode not available */    /* Update the register information */    memcpy(regs, rp, sizeof(regs));    if (__svgalib_infotable[mode].colors == 16) {	/* switch from 256 to 16 color mode (from XFree86) */	regs[SEQ + 4] &= 0xf7;	/* Switch off chain 4 mode */    }    __svgalib_setregs(regs);    ali_setregs(regs, mode);    return 0;}/* ali_unlock()                                         Unlock ALI registers * Enable register changes *  */static void ali_unlock(void){    int temp;    temp = GETB(__svgalib_CRT_I, 0x1a);    outb(__svgalib_CRT_D, temp | 0x10);    /* Unprotect CRTC[0-7] */    temp = GETB(__svgalib_CRT_I, 0x11);    outb(__svgalib_CRT_D, temp & 0x7f);}/* ali_lock()                                           Lock Ali registers * Prevents registers from accidental change *  */static void ali_lock(void){    int tmp;    /* Protect CRTC[0-7] */    tmp = GETB(__svgalib_CRT_I, 0x11);    outb(__svgalib_CRT_D, tmp | 0x80);    tmp = GETB(__svgalib_CRT_I, 0x1a);    outb(__svgalib_CRT_D, tmp & 0xef);}static int cwg(void){    int t, t1, t2, t3;    t = inb(GRA_I);    t1 = GETB(GRA_I, 0x0b);    t2 = t1 & 0x30;    outb(GRA_D, t2 ^ 0x30);    t3 = ((inb(GRA_D) & 0x30) ^ 0x30);    outb(GRA_D, t1);    outb(GRA_I, t);    return (t2 == t3);}/* ali_test()                                           Probe for Ali card * Checks for Ali segment register, then chip type and memory size. *  * Returns 1 for Ali, 0 otherwise. */static int ali_test(void){    int tmp, ov;    ali_unlock();    tmp = inb(__svgalib_CRT_I);    ov = GETB(__svgalib_CRT_I, 0x1a);    outb(__svgalib_CRT_D, ov & 0xef);    if (cwg()) {	ali_lock();	return 0;    }    outb(__svgalib_CRT_D, ov | 0x10);    if (!cwg()) {	ali_lock();	return 0;    }    return ali_init(0, 0, 0);}/* ali_setpage( int page )                              Set read/write pages * Sets both read and write extended segments (64k bank number) */static void ali_setpage(int page){    outw(0x3d6, (last_page = page) | (page << 8));}/* ali_setrdpage( int page )                            Set read page * Sets read extended segment (64k bank number) */static void ali_setrdpage(int page){    last_page = page;    outb(0x3d6, page);}/* ali_setwrpage( int page )                            Set write page * Sets write extended segment (64k bank number) */static void ali_setwrpage(int page){    last_page = page;    outb(0x3d7, page);}/* ali_setdisplaystart( int address )                   Set display address * Sets display start address. */static void ali_setdisplaystart(int address){    address >>= 3;    outw(__svgalib_CRT_I, 0x0c | (address & 0x00ff00));    outw(__svgalib_CRT_I, 0x0d | ((address & 0x00ff) << 8));    outw(__svgalib_CRT_I, 0x20 | ((address & 0x070000) >> 8));}/* ali_setlogicalwidth( int width )                     Set scanline length * Set logical scanline length (usually multiple of 8) * Multiples of 8 to 2040 */static void ali_setlogicalwidth(int width){    outw(CRT_IC, 0x13 + (width >> 3) * 256);	/* lw3-lw11 */}/* ali_init ( int force, int par1, int par2)            Initialize chipset * Detects ALI chipset type and installed video memory. * Returns 1 if chipset is supported, 0 otherwise */static int ali_init(int force, int par1, int par2){    if (force) {	ali_memory = par2;    } else {	ali_memory = ali_memorydetect();    }    if (__svgalib_driver_report) {	printf("Using ALI driver (ALI2301, %dK).\n", ali_memory);    }    __svgalib_driverspecs = &__svgalib_ali_driverspecs;    /* fix infotable entry */    infotable[G640x480x16M].xbytes = 2048;    __svgalib_banked_mem_base=0xa0000;    __svgalib_banked_mem_size=0x10000;    return 1;}/* ali_memorydetect()                           Report installed video RAM * Returns size (in Kb) of installed video memory * Defined values are 256, 512, 1024, and 2048 */static int ali_memorydetect(void){    int tmp;    tmp = GETB(__svgalib_CRT_I, 0x1e);    switch (tmp & 3) {    case 0:	return 256;    case 1:	return 512;    case 2:	return 1024;    case 3:	return 2048;    default:	printf("ALI driver: More than 2MB installed. Using 2MB.\n");	return 2048;    }}/* SETB (port,index,value)                      Set extended register * Puts a specified value in a specified extended register. * Splitting this commonly used instruction sequence into its own subroutine * saves about 100 bytes of code overall ... */static void SETB(int port, int idx, int value){    if (idx != -1)	outb(port, idx);    outb(port + (idx != -1), value);}/* GETB (port,index)                            Returns ext. register * Returns value from specified extended register. * As with SETB, this tightens the code considerably. */static int GETB(int port, int idx){    if (idx != -1)	outb(port, idx);    return inb(port + (idx != -1));}/* Function table (exported) */DriverSpecs __svgalib_ali_driverspecs ={    ali_saveregs,    ali_setregs,    ali_unlock,    ali_lock,    ali_test,    ali_init,    ali_setpage,    ali_setrdpage,    ali_setwrpage,    ali_setmode,    ali_modeavailable,    ali_setdisplaystart,    ali_setlogicalwidth,    ali_getmodeinfo,    0,				/* bitblt */    0,				/* imageblt */    0,				/* fillblt */    0,				/* hlinelistblt */    0,				/* bltwait */    0,				/* extset */    0,    0,				/* linear */    NULL,			/* accelspecs */    NULL,                       /* Emulation */};

⌨️ 快捷键说明

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