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

📄 mach32.c

📁 linux 下svgalib编的一个界面程序示例
💻 C
📖 第 1 页 / 共 5 页
字号:
static volatile char *mach32_aperture = NULL;static volatile int dummy;static signed char mach32_search_clk(int clk);static void mach32_setstate(accelstate which);static void mach32_blankadj(int adj);static void mach32_modfill(const mode_entry * mode, int modemask, int forcein);static int mach32_test(void);static int mach32_init(int force, int chiptype, int memory);static void mach32_i_bltwait(void);static void mach32_bltwait(void);static void mach32_wait(void);static void mach32_experm(void);static int mach32_eeclock(register int ati33);static void mach32_eekeyout(register int ati33, register int offset, register int mask);static int mach32_eeget(int offset);static int mach32_saveregs(unsigned char regs[]);static void mach32_setregs(const unsigned char regs[], int mode);static void mach32_unlock(void);static void mach32_lock(void);static int mach32_sav_dac(int offset, unsigned char regs[]);static int mach32_set_dac(int dac_mode, int clock_intended, int xres);static void mach32_setpage(int page);static void mach32_setrdpage(int page);static void mach32_setwrpage(int page);static void mach32_setappage(int page);static void mach32_setdisplaystart(int address);static void mach32_setlogicalwidth(int width);static int mach32_modeavailable(int mode);static void mach32_getmodeinfo(int mode, vga_modeinfo * modeinfo);static int mach32_setmode(int mode, int previous);static void mach32_bitblt(int srcaddr, int destaddr, int w, int h, int pitch);static void mach32_fillblt(int destaddr, int w, int h, int pitch, int c);static void mach32_imageblt(void *srcaddr, int destaddr, int w, int h, int pitch);static void mach32_memimageblt(void *srcaddr, int destaddr, int w, int h, int pitch);static void mach32_hlinelistblt(int ymin, int n, int *xmin, int *xmax, int pitch, int c);static void mach32_readconfig(void);static void mach32_final_modefixup(void);static int mach32_ext_set(unsigned what, va_list params);static int mach32_accel(unsigned operation, va_list params);static void mach32_ge_reset(void);static void slow_queue(unsigned short mask);static void mach32_savepalette(unsigned char *red, unsigned char *green, unsigned char *blue);static void mach32_restorepalette(const unsigned char *red, const unsigned char *green,				  const unsigned char *blue);static int  mach32_setpalette(int index, int red, int green, int blue);static void mach32_getpalette(int index, int *red, int *green, int *blue);static int mach32_screenon(void);static void mach32_waitretrace(void);DriverSpecs __svgalib_mach32_driverspecs ={    mach32_saveregs,		/* saveregs */    mach32_setregs,		/* setregs */    mach32_unlock,		/* unlock */    mach32_lock,		/* lock */    mach32_test,    mach32_init,    mach32_setpage,		/* __svgalib_setpage */    mach32_setrdpage,		/* __svgalib_setrdpage */    mach32_setwrpage,		/* __svgalib_setwrpage */    mach32_setmode,		/* setmode */    mach32_modeavailable,	/* modeavailable */    mach32_setdisplaystart,	/* setdisplaystart */    mach32_setlogicalwidth,	/* setlogicalwidth */    mach32_getmodeinfo,		/* getmodeinfo */    mach32_bitblt,		/* bitblt */    mach32_imageblt,		/* imageblt */    mach32_fillblt,		/* fillblt */    mach32_hlinelistblt,	/* hlinelistblt */    mach32_bltwait,		/* bltwait */    mach32_ext_set,    mach32_accel,    0,				/* linear -- mach32 driver handles it differently */    NULL,			/* Accelspecs */    NULL,			/* Emulation */};static Emulation mach32_vgaemul = {    mach32_savepalette,    mach32_restorepalette,    mach32_setpalette,    mach32_getpalette,    NULL, /* void (*savefont)(void); */    NULL, /* void (*restorefont)(void); */    NULL, /* int (*screenoff)(void); */    mach32_screenon,    mach32_waitretrace,};#ifdef FAST_MEMCPY/* This memcpy is immediately derived from memset as given in speedtest.c in this   same svgalib package written by Harm Hanemaayer */static inline void * fast_memcpy(void *dest, void *source, size_t count){    __asm__(	       "cld\n\t"	       "cmpl $12,%%edx\n\t"	       "jl 1f\n\t"	/* if (count >= 12) */	       "movl %%edx,%%ecx\n\t"	       "negl %%ecx\n\t"	       "andl $3,%%ecx\n\t"	/* (-s % 4) */	       "subl %%ecx,%%edx\n\t"	/* count -= (-s % 4) */	       "rep ; movsb\n\t"	/* align to longword boundary */	       "movl %%edx,%%ecx\n\t"	       "shrl $2,%%ecx\n\t"    /* Doing any loop unrolling here proved to SLOW!!! down       the copy on my system, at least it didn't show any speedup. */	       "rep ; movsl\n\t"	/* copy remaining longwords */	       "andl $3,%%edx\n"	/* copy last few bytes */	       "1:\tmovl %%edx,%%ecx\n\t"	/* <= 12 entry point */  "rep ; movsb\n\t":  /* no outputs */ :    /* inputs */    /* SI= source address */ "S"(source),    /* DI= destination address */ "D"(dest),  /* CX= words to transfer */ "d"(count):    /* eax, edx, esi, edi, ecx destructed: */ "%eax", "%edx", "%esi", "%edi", "%ecx");    return dest;}#else#define fast_memcpy memcpy#endifstatic inline int max(int a, int b){    return (a > b) ? a : b;}static inline void checkqueue(int n){				/* This checks for at least n free queue positions *//*Prepare mask: */    unsigned short mask = (unsigned short) (0xffff0000 >> n);    int i = BUSYWAIT;    while (i--)	if (!(inw(EXT_FIFO_STATUS) & mask))	    return;    slow_queue(mask);}static void slow_queue(unsigned short mask){    clock_t clk_time;    clk_time = clock();    do {	if (!(inw(EXT_FIFO_STATUS) & mask))	    return;    }    while ((clock() - clk_time) < (CLOCKS_PER_SEC * ADDIWAIT));    mach32_ge_reset();		/* Give up */}static void mach32_ge_reset(void){				/* This is intended as a safety bailout if we locked				   up the card. */    int queue_stat, ioerr, ge_stat;    int i = 1000000;    volatile int dummy;/* Provide diagnostics: */    ioerr = inw(SUBSYS_STAT);    queue_stat = inw(EXT_FIFO_STATUS);    ge_stat = inw(GE_STAT);    outw(SUBSYS_CNTL, 0x800f);	/*Reset GE, disable all IRQ, reset all IRQ state bits */    while (i--)	dummy++;    outw(SUBSYS_CNTL, 0x400f);	/*Continue normal operation *//* Better reconfigure all used registers */    mach32_accelstate = R_UNKNOWN;    CRITICAL = 0;		/* Obviously we are idle */    puts("\asvgalib: mach32: Warning! GE_Engine timed out, draw command\n"	 "was probably corrupted! If you have a very fast machine (10*Pentium)\n"	 "raise BUSYWAIT and ADDIWAIT in mach32.c, may also be a driver/card bug,\n"	 "so report detailed info to me (Michael Weller).\nBUT:\n"	 "This reaction is normal when svgalib is killed in a very critical operation\n"	 "by a fatal signal like INT (pressing ^C). In this situation this reset just\n"	 "guarantees that you can continue working on the console, so in this case\n"	 "PLEASE don't bloat my mailbox with bug reports. Thx, Michael.");    printf("POST-Mortem:\n\tSubsys stat: %04x - %sIOerror (is usually a queue overrun)\n"	   "\tGE stat    : %04x - engine %s, %sdata ready for host.\n\tQueue stat : %04x\n",	   ioerr, (ioerr & 4) ? "" : "no ", ge_stat,	   (ge_stat & GE_BUSY) ? "busy" : "idle", (ge_stat & 0x100) ? "" : "no ", queue_stat);}static void mach32_setstate(accelstate which){				/* Set GE registers to values assumed elsewhere */    mach32_accelstate = which;    checkqueue(10);    /*Effectively switch off hardware clipping: */    outw(MULTI_FUNC_CNTL, 0x1000 | (0xfff & -1));	/*TOP */    outw(MULTI_FUNC_CNTL, 0x2000 | (0xfff & -1));	/*LEFT */    outw(MULTI_FUNC_CNTL, 0x3000 | 1535);	/*BOTTOM */    outw(MULTI_FUNC_CNTL, 0x4000 | 1535);	/*RIGHT */    /*Same for ATI EXT commands: */    outw(EXT_SCISSOR_T, 0xfff & -512);	/*TOP */    outw(EXT_SCISSOR_L, 0xfff & -512);	/*LEFT */    outw(EXT_SCISSOR_B, 1535);	/*BOTTOM */    outw(EXT_SCISSOR_R, 1535);	/*RIGHT */    outw(MULTI_FUNC_CNTL, 0xa000);    outw(DP_CONFIG, 0x3291);    checkqueue(4);    outw(DEST_CMP_FN, 0);    if (which == R_STANDARD) {	checkqueue(2);	outw(BKGD_MIX, 0x0027);	/* Not used .. however ensure PIX_TRANS is not used */	outw(ALU_FG_FN, 7);    } else {	checkqueue(5);	outw(GE_OFFSET_LO, mach32_ge_off_l);	outw(GE_OFFSET_HI, mach32_ge_off_h);	outw(GE_PITCH, mach32_ge_pitch);	outw(BKGD_MIX, mach32_bkgd_alu_fn);	outw(FRGD_MIX, mach32_frgd_alu_fn | 0x20);	checkqueue(6);	outw(ALU_BG_FN, mach32_bkgd_alu_fn);	outw(ALU_FG_FN, mach32_frgd_alu_fn);        outw(FRGD_COLOR, mach32_frgd_col);        outw(BKGD_COLOR, mach32_bkgd_col);	outw(RD_MASK, (infotable[CM].colors == 32768) ? 0x7fff : 0xffff);	outw(LINEDRAW_OPT, 0);    }}static void mach32_setdisplaystart(int address){#ifdef DEBUG    printf("mach32_setdisplaystart(%x)\n", address);#endif    mach32_ge_off_l = address >> 2;    outw(CRT_OFFSET_LO, mach32_ge_off_l);    mach32_ge_off_h = 0xff & (address >> 18);    outw(CRT_OFFSET_HI, mach32_ge_off_h);    if (mach32_accelstate == R_EXTENDED) {	checkqueue(2);	outw(GE_OFFSET_LO, mach32_ge_off_l);	outw(GE_OFFSET_HI, mach32_ge_off_h);    }    __svgalib_vga_driverspecs.setdisplaystart(address);}static void mach32_setlogicalwidth(int width){    register int mywidth;#ifdef DEBUG    printf("mach32_setlogicalwidth(%d)\n", width);#endif    if (infotable[CM].bytesperpixel) {	/* always >= 1 for Mach32 modes */	/*Unfortunately the Mach32 expects this value in Pixels not bytes: */	mywidth = width / (infotable[CM].bytesperpixel);	mywidth = (mywidth >> 3) & 0xff;#ifdef DEBUG	printf("mach32_setlogicalwidth: Mach32 width to %d pels.\n", mywidth * 8);#endif	outw(CRT_PITCH, mywidth);	mach32_ge_pitch = mywidth;	if (mach32_accelstate == R_EXTENDED) {	    checkqueue(1);	    outw(GE_PITCH, mywidth);	}    }    __svgalib_vga_driverspecs.setlogicalwidth(width);}static void mach32_setpage(int page){    register unsigned short tmp;#ifdef DEBUG    printf("mach32_setpage(%d)\n", page);#endif    if (mach32_pagemode != PAGE_BOTH) {	outb(ATIPORT, ATISEL(0x3E));	tmp = inb(ATIPORT + 1) & 0xf7;	tmp = (tmp << 8) | ATISEL(0x3E);	outw(ATIPORT, tmp);	mach32_pagemode = PAGE_BOTH;    }    tmp = (page << 9) & 0x1e00;    outw(ATIPORT, ATISEL(0x32) | tmp);    outb(ATIPORT, ATISEL(0x2e));    tmp = (inb(ATIPORT + 1) & 0xfc) | ((page >> 4) & 3);    outw(ATIPORT, ATISEL(0x2e) | (tmp << 8));}static void mach32_setwrpage(int page){    register unsigned short tmp;    if (mach32_pagemode != PAGE_DIFF) {	outb(ATIPORT, ATISEL(0x3E));	outw(ATIPORT, (ATISEL(0x3E) << 8) | (inb(ATIPORT + 1) | 8));	mach32_pagemode = PAGE_DIFF;    }    outb(ATIPORT, ATISEL(0x32));    tmp = inb(ATIPORT + 1) & 0xe1;    outw(ATIPORT, (ATISEL(0x32) << 8) | ((page << 1) & 0x1e));    outb(ATIPORT, ATISEL(0x2e));    tmp = inb(ATIPORT + 1) & 0xfc;    outw(ATIPORT, (ATISEL(0x2e) << 8) | tmp | ((page >> 4) & 3));}static void mach32_setrdpage(int page){    register unsigned short tmp;    if (mach32_pagemode != PAGE_DIFF) {	outb(ATIPORT, ATISEL(0x3E));	outw(ATIPORT, (ATISEL(0x3E) << 8) | (inb(ATIPORT + 1) | 8));	mach32_pagemode = PAGE_DIFF;    }    outb(ATIPORT, ATISEL(0x32));    tmp = inb(ATIPORT + 1) & 0x1e;    if (page & 8)	tmp |= 1;    outw(ATIPORT, (ATISEL(0x32) << 8) | tmp | ((page << 5) & 0xe0));    outb(ATIPORT, ATISEL(0x2e));    tmp = inb(ATIPORT + 1) & 0xf3;    outw(ATIPORT, (ATISEL(0x2e) << 8) | tmp | ((page >> 2) & 0xc));}static void mach32_setappage(int page){    outw(MEM_CFG, (mach32_memcfg | (0xc & (page << 2))));}static int mach32_sav_dac(int offset, unsigned char regs[]){/* I was unable to read out the actual DAC_config, so   we just save which mode we are in: */    regs[offset] = mach32_dacmode;#ifdef DEBUG    printf("mach32_sav_dac(%d,...): Dac:%d, dac_mode:%d\n", offset, mach32_dac,	   regs[offset]);#endif    return offset + 1;}static inline void clean_clocks(void){    outw(CLOCK_SEL, (inw(CLOCK_SEL) & ~0x7f) | 0x11);}static int mach32_set_dac(int dac_mode, int clock_intended, int xres){    unsigned short act_ge_conf;    const unsigned char *dac_reg;    act_ge_conf = inw(R_EXT_GE_CONF) & 0x8fff;#ifdef DEBUG    printf("mach32_set_dac(%d,%d): Dac:%d\n", dac_mode, clock_intended, mach32_dac);#endif    mach32_dacmode = dac_mode;    dac_mode &= 0x7f;    mach32_blankadj((mach32_dac == MACH32_ATI68830) ? 0x4 : 0xc);    switch (mach32_dac) {    case MACH32_SC11483:	dac_reg = mach32_dac1;#ifdef DEBUG	fputs("DAC1: ", stdout);#endif	if (dac_mode <= DAC_MODE565)	    goto dac1_4;	break;    case MACH32_ATI6871:	/*This one is a nightmare: */	clean_clocks();	outw(EXT_GE_CONF, 0x201a);	switch (dac_mode) {	default:	case DAC_MODE8:	case DAC_MODEMUX:	    outb(DAC1, 0x00);	    outb(DAC2, 0x30);	    outb(DAC3, 0x2d);#ifdef DEBUG	    puts("DAC2: 0x00 0x30 0x2d (8bpp)");#endif	    if (dac_mode != DAC_MODEMUX)		break;	    outb(DAC2, 0x09);	    outb(DAC3, 0x1d);	    outb(DAC1, 0x01);	    mach32_blankadj(1);#ifdef DEBUG	    puts("DAC2: 0x01 0x09 0x1d (8bpp MUX)");#endif	    break;	case DAC_MODE555:	case DAC_MODE565:	case DAC_MODERGB:	    mach32_blankadj(1);	case DAC_MODE32B:	    outb(DAC1, 0x01);	    if ((!(clock_intended & 0xc0)) && (!(mach32_dacmode & DAC_SEMICLK))) {		outb(DAC2, 0x00);#ifdef DEBUG		puts("DAC2: 0x01 0x00 0x0d (16/24bpp)");#endif	    } else {		clock_intended &= 0xff3f;

⌨️ 快捷键说明

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