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

📄 laguna.c

📁 linux 下svgalib编的一个界面程序示例
💻 C
📖 第 1 页 / 共 2 页
字号:
/*Laguna chipset driver for cirrus logic 5462, 5464, 5465Only tested on 5464.Problems:    mouse cursor does not work.    secondary (mmio only) not tested.    fifo threshold needs more tuning.*/#include <stdlib.h>#include <stdio.h>		#include <string.h>#include <unistd.h>#include "vga.h"#include "libvga.h"#include "driver.h"#include "timing.h"#include "vgaregs.h"#include "interface.h"#include "accel.h"#include "vgapci.h"struct lagunahw {    unsigned char crt[5];    unsigned char gra[3];    unsigned char seq[3];    unsigned char pal_state;    unsigned char bclk;    unsigned char tile;     unsigned short tiling_control;    unsigned short control;    unsigned short format;    unsigned short cur_x;    unsigned short cur_y;    unsigned short cur_preset;    unsigned short cur_misc;    unsigned short cur_address;    unsigned short disp_thresh;    unsigned int pcifc;};#define LAGUNAREG_SAVE(i) (VGA_TOTAL_REGS+i)#define LAGUNA_TOTAL_REGS (VGA_TOTAL_REGS + sizeof(struct lagunahw))enum {    L5462=0, L5464, L5465};static int laguna_init(int, int, int);static void laguna_unlock(void);static void laguna_lock(void);void __svgalib_lagunaaccel_init(AccelSpecs * accelspecs, int bpp, int width_in_pixels);static int laguna_memory, laguna_chiptype;static int laguna_is_linear, laguna_linear_base, laguna_mmio_base;static CardSpecs *cardspecs;static inline unsigned int laguna_readb(int a) {    return *(MMIO_POINTER+a);}static inline unsigned int laguna_readw(int a) {    return *(unsigned short *)(MMIO_POINTER+a);}static inline unsigned int laguna_readl(int a) {    return *(unsigned int *)(MMIO_POINTER+a);}static inline void laguna_writeb(int a, unsigned int d) {    *(MMIO_POINTER+a)=d;}static inline void laguna_writew(int a, unsigned int d) {    *(unsigned short *)(MMIO_POINTER+a)=d;}static inline void laguna_writel(int a, unsigned int d) {    *(unsigned int *)(MMIO_POINTER+a)=d;}static void laguna_setpage(int page){    __svgalib_outgra(0x09,page*4);}static int __svgalib_laguna_inlinearmode(void){return laguna_is_linear;}/* Fill in chipset specific mode information */static void laguna_getmodeinfo(int mode, vga_modeinfo *modeinfo){    if(modeinfo->colors==16)return;    modeinfo->maxpixels = laguna_memory*1024/modeinfo->bytesperpixel;    modeinfo->maxlogicalwidth = 4088;    modeinfo->startaddressrange = laguna_memory * 1024 - 1;    modeinfo->haveblit = 0;    modeinfo->flags &= ~HAVE_RWPAGE;    if (modeinfo->bytesperpixel >= 1) {	if(laguna_linear_base)modeinfo->flags |= CAPABLE_LINEAR;        if (__svgalib_laguna_inlinearmode())	    modeinfo->flags |= IS_LINEAR;    }}/* Read and save chipset-specific registers */static int laguna_saveregs(unsigned char regs[]){     struct lagunahw *l=(struct lagunahw *)(regs+VGA_TOTAL_REGS);    laguna_unlock();		        l->crt[0]= __svgalib_incrtc(0x19);    l->crt[1]= __svgalib_incrtc(0x1a);    l->crt[2]= __svgalib_incrtc(0x1b);    l->crt[3]= __svgalib_incrtc(0x1d);    l->crt[4]= __svgalib_incrtc(0x1e);    l->gra[0]= __svgalib_ingra(0x09);    l->gra[1]= __svgalib_ingra(0x0a);    l->gra[2]= __svgalib_ingra(0x0b);    l->seq[0]= __svgalib_inseq(0x0e);    l->seq[1]= __svgalib_inseq(0x1e);    l->seq[2]= __svgalib_inseq(0x07);    if(laguna_chiptype==L5465)        l->tiling_control=laguna_readw(0x2c4);    l->control=laguna_readw(0x402);    if(laguna_chiptype==L5465)        l->bclk=laguna_readb(0x2c0);        else l->bclk=laguna_readb(0x8c);    l->tile=laguna_readb(0x407);    l->pal_state=laguna_readb(0xb0);    l->format=laguna_readw(0xc0);    l->cur_x=laguna_readw(0xe0);    l->cur_y=laguna_readw(0xe2);    l->cur_preset=laguna_readw(0xe4);    l->cur_misc=laguna_readw(0xe6);    l->cur_address=laguna_readw(0xe8);    l->disp_thresh=laguna_readw(0xea);    l->pcifc=laguna_readl(0x3fc);        return LAGUNA_TOTAL_REGS - VGA_TOTAL_REGS;}/* Set chipset-specific registers */static void laguna_setregs(const unsigned char regs[], int mode){      struct lagunahw *l=(struct lagunahw *)(regs+VGA_TOTAL_REGS);    laguna_unlock();		    __svgalib_outcrtc(0x19,l->crt[0]);    __svgalib_outcrtc(0x1a,l->crt[1]);    __svgalib_outcrtc(0x1b,l->crt[2]);    __svgalib_outcrtc(0x1d,l->crt[3]);    __svgalib_outcrtc(0x1e,l->crt[4]);    __svgalib_outgra(0x09,l->gra[0]);    __svgalib_outgra(0x0a,l->gra[1]);    __svgalib_outgra(0x0b,l->gra[2]);    __svgalib_outseq(0x0e,l->seq[0]);    __svgalib_outseq(0x1e,l->seq[1]);    __svgalib_outseq(0x07,l->seq[2]);    if(laguna_chiptype==L5465)        laguna_writew(0x2c4,l->tiling_control);    laguna_writew(0x402,l->control);    if(laguna_chiptype==L5465)        laguna_writeb(0x2c0,l->bclk);        else laguna_writeb(0x8c,l->bclk);    laguna_writew(0x407,l->tile);    laguna_writew(0xb0,l->pal_state);    laguna_writew(0xc0,l->format);    laguna_writew(0xe0,l->cur_x);    laguna_writew(0xe2,l->cur_y);    laguna_writew(0xe4,l->cur_preset);    laguna_writew(0xe6,l->cur_misc);    laguna_writew(0xe8,l->cur_address);    laguna_writew(0xea,l->disp_thresh);    laguna_writel(0x3fc,l->pcifc);}/* Return nonzero if mode is available */static int laguna_modeavailable(int mode){    struct info *info;    ModeTiming *modetiming;    ModeInfo *modeinfo;    if ((mode < G640x480x256 )	|| mode == G720x348x2)	return __svgalib_vga_driverspecs.modeavailable(mode);    info = &__svgalib_infotable[mode];    if (laguna_memory * 1024 < info->ydim * info->xbytes)	return 0;    modeinfo = __svgalib_createModeInfoStructureForSvgalibMode(mode);    modetiming = malloc(sizeof(ModeTiming));    if (__svgalib_getmodetiming(modetiming, modeinfo, cardspecs)) {	free(modetiming);	free(modeinfo);	return 0;    }    free(modetiming);    free(modeinfo);    return SVGADRV;}/* Local, called by laguna_setmode(). */#define REF 14318static int laguna_findclock(int clock, int *on, int *om, int *op, int *opp){    int n, m, diff, best, bestm;        *opp=0;    while(clock<20000) {        clock*=2;        *opp=+1;    }        if(clock<40000) {        clock *= 2;        *op=1;    } else *op=0;        best=clock;    bestm=5;    for(m=6; m<30;m++) {        n=clock*m/REF;        if((n<64)||(n>127)) continue;        diff=clock-(n*REF/m);        if(diff<0)diff=-diff;        if(diff<best) {            best=diff;            bestm=m;        }    }        if((best==0) || (clock/best>100)) {        *on=clock*bestm/REF;        *om=bestm;        return 0;    } else {        fprintf(stderr,"Can't find clock %iKHz.\n",clock);        return -1;    }        }static void laguna_initializemode(unsigned char *moderegs,			    ModeTiming * modetiming, ModeInfo * modeinfo, int mode){    struct lagunahw *l=(struct lagunahw *)(moderegs+VGA_TOTAL_REGS);    int hd, htot, hss, hse, hbs, hbe;    int vd, vtot, vss, vse, vbs, vbe;    int offset;    int n,m,p,pp;       __svgalib_setup_VGA_registers(moderegs, modetiming, modeinfo);            if(laguna_chiptype==L5465) {        l->tiling_control=laguna_readw(0x2c4);        l->tiling_control &= ~0x80; /* disable tiling */    }    l->control=laguna_readw(0x402) & 0x87ff; /* narrow tiles */    l->control |= 0x1000; /* disable tiling */    l->disp_thresh=laguna_readw(0xea)&0xffe0;    l->disp_thresh &= 0x3fbf; /* 1-way interleave and narrow tiles */    switch(modeinfo->bitsPerPixel) {        case 8:        case 15:        case 16:            l->disp_thresh |= 0x10;            break;        case 24:        case 32:            l->disp_thresh |= 0x20;            break;        default:            l->disp_thresh |= 0x18;    }                l->pcifc=laguna_readl(0x3fc);    l->pcifc |= 0x10000000;    if(laguna_chiptype==L5465)        l->bclk=laguna_readb(0x2c0);

⌨️ 快捷键说明

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