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

📄 oak.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 1993 Harm Hanemaayer   partially copyrighted (C) 1993 by Hartmut Schirmer   OTI-067/077/087 support driver release 1.2 (12 September 1994)   Rewritten/fleshed out by Christopher Wiles (a0017097@wsuaix.csc.wsu.edu)   Features in this release:    * _real_ 640x480x256 mode   * 800x600x16, 800x600x256 modes   * 1024x768x16, 1024x768x256 modes   * 640x480x32K, 800x600x32K modes   * 1280x1024x16 mode (untested)   * OTI-087 chipset support, including 2M variants   Still left to do:   * linear addressing   The stubs are in the code, and can be activated by setting   OTI87_LINEAR_OK to 1 (I've set it to 0).  The '87 goes into and out   of linear mode just fine; I'm having a hell of a time getting SVGALIB   to use the linear buffer instead of the bank switched buffer at A0000.   In any event, if someone feels adventurous, the bones are present.   * 64K/16M modes   64K/16M modes appear to be broken.  I couldn't even switch them in   from Oak's own DOS test utility ...   * 1280x1024 modes   I've included a definition for the 16 color mode.  I couldn't test   it, as my monitor's maximum resolution is 1024x768.  According to   the documentation, a 2 meg board should be able to do an interlaced   1280x1024x256.  I couldn't force Oak's BIOS to enter that mode.   Could be because I have only 1 meg on board. */#include <stdio.h>#include <string.h>#include "vga.h"#include "libvga.h"#include "driver.h"#include <sys/types.h>#include "oak.regs"#define OTI_MISC_DATA EXT+01#define OTI_BCOMPAT_DATA EXT+02#define OTI_SEGMENT_DATA EXT+03#define OTI_CONFIG_DATA	EXT+04#define OTI_OVERFLOW_DATA EXT+05#define OTI_HSYNC2_DATA EXT+06#define OTI_OVERFLOW2_DATA EXT+07#define CLOCK_DATA EXT + 08#define OVERFLOW_DATA EXT + 09#define OTI87_HSYNC2_DATA EXT+10#define OTI87_XCRTC_DATA EXT+11#define OTI87_COLORS_DATA EXT+12#define OTI87_FIFO_DATA EXT+13#define OTI87_MODESELECT_DATA EXT+14#define OTI87_FEATURE_DATA EXT+15#define OTI87_XREADSEGMENT_DATA EXT+16#define OTI87_XWRITESEGMENT_DATA EXT+17#define OTI87_RAMDAC_DATA EXT+18#define OTI_INDEX 0x3DE		/* Oak extended index register */#define OTI_R_W 0x3DF		/* Oak extended r/w register */#define OTI_CRT_CNTL 0xC	/* Oak CRT COntrol Register */#define OTI_MISC  0xD		/* Oak Misc register */#define OTI_BCOMPAT  0xE	/* Oak Back compat register */#define OTI_SEGMENT  0x11	/* Oak segment register */#define OTI_CONFIG  0x12	/* Oak config register */#define OTI_OVERFLOW  0x14	/* Oak overflow register */#define OTI_OVERFLOW2  0x16	/* Oak overflow2 register */#define OTI87_PRODUCT 0x00	/* Oak product register */#define OTI87_STATUS 0x02	/* Oak status register */#define OTI87_VIDMAP 0x05	/* Oak video memory register */#define OTI87_CLOCK 0x06	/* Oak clock select register */#define OTI87_OVERFLOW 0x14	/* Oak overflow register */#define OTI87_HSYNC2 0x15	/* Oak hsynch/2 register */#define OTI87_XCRTC 0x17	/* Oak extended CRTC register */#define OTI87_COLORS 0x19	/* Oak color range register */#define OTI87_FIFO 0x20		/* Oak FIFO depth register */#define OTI87_MODESELECT 0x21	/* Oak mode select register */#define OTI87_FEATURE 0x22	/* Oak feature select register */#define OTI87_XREADSEGMENT 0x23	/* Oak extended read segment reg. */#define OTI87_XWRITESEGMENT 0x24	/* Oak extended write seg. reg. */#define OTI87_XCOMMONSEGMENT 0x25	/* Oak extended common register */#define OTI87_OK_LINEAR 0	/* Set to 1 for linear addressing */#define DAC_SC11487 0x3c6	/* Sierra DAC command register */#define DAC_REVERT 0x3c8	/* Clears DAC from command mode */static int oak_chiptype;static int oak_memory;static int oak_lockreg_save;static unsigned char last_page = 0;static unsigned char *VGAMemory_Save;static int oak_init(int, int, int);static int oak_interlaced(int mode);static int oak_memorydetect(void);static int oak_chipdetect(void);static int oak_inlinearmode(void);static int OAKGetByte(int);static void oak_unlock(void);static void oak_setlinearmode(void);static void oak_clearlinearmode(void);static void oak_setpage(int page);static void OAK_WriteDAC(int function);static void OAKSetByte(int, int);static void * linearframebuffer;/* Mode table */static ModeTable oak_modes[] ={/* *INDENT-OFF* */    OneModeEntry(640x480x256),    OneModeEntry(640x480x32K),    OneModeEntry(800x600x16),    OneModeEntry(1024x768x16),    OneModeEntry(800x600x256),    OneModeEntry(800x600x32K),    OneModeEntry(1024x768x256),    OneModeEntry(1280x1024x16),    END_OF_MODE_TABLE/* *INDENT-ON* */};/* oak_getmodeinfo( int mode, vga_modeinfo *modeinfo)   Tell SVGALIB stuff * Return mode information (blityes/no, start address, interlace, linear */static void oak_getmodeinfo(int mode, vga_modeinfo * modeinfo){    if (modeinfo->bytesperpixel > 0) {	modeinfo->maxpixels = oak_memory * 1024 / modeinfo->bytesperpixel;    } else {	modeinfo->maxpixels = oak_memory * 1024;	/* any val */    }    modeinfo->maxlogicalwidth = 2040;    modeinfo->startaddressrange = 0xfffff;    modeinfo->haveblit = 0;    modeinfo->flags |= HAVE_RWPAGE;    if (oak_interlaced(mode)) {	modeinfo->flags |= IS_INTERLACED;    }    if ((oak_chiptype == 87) & (OTI87_OK_LINEAR == 1)) {	modeinfo->flags |= CAPABLE_LINEAR;	modeinfo->flags |= EXT_INFO_AVAILABLE;	modeinfo->chiptype = 87;	modeinfo->aperture_size = oak_memorydetect();	modeinfo->set_aperture_page = oak_setpage;	if (oak_inlinearmode()) {	    modeinfo->flags |= IS_LINEAR;	    /* The following line was missing? */	    modeinfo->linear_aperture = linearframebuffer;	}    }}/* oak_saveregs( unsigned char regs[] )                 Save extended regs * Save extended registers into regs[]. * OTI-067/077 have eight registers * OTI-087 has nineteen registers (only 11 used for native mode) * */static int oak_saveregs(unsigned char regs[]){    oak_unlock();    regs[OTI_SEGMENT_DATA] = OAKGetByte(OTI_SEGMENT);    regs[OTI_MISC_DATA] = OAKGetByte(OTI_MISC);    regs[OTI_BCOMPAT_DATA] = OAKGetByte(OTI_BCOMPAT);    regs[OTI_CONFIG_DATA] = OAKGetByte(OTI_CONFIG);    regs[OTI_OVERFLOW_DATA] = OAKGetByte(OTI_OVERFLOW);    regs[OTI_HSYNC2_DATA] = OAKGetByte(OTI87_HSYNC2);    regs[OTI_OVERFLOW2_DATA] = OAKGetByte(OTI_OVERFLOW2);    if (oak_chiptype == 87) {	regs[EXT + 8] = OAKGetByte(OTI87_CLOCK);	regs[EXT + 9] = OAKGetByte(OTI87_OVERFLOW);	regs[OTI87_HSYNC2_DATA] = OAKGetByte(OTI87_HSYNC2);	regs[OTI87_XCRTC_DATA] = OAKGetByte(OTI87_XCRTC);	regs[OTI87_COLORS_DATA] = OAKGetByte(OTI87_COLORS);	regs[OTI87_FIFO_DATA] = OAKGetByte(OTI87_FIFO_DATA);	regs[OTI87_MODESELECT_DATA] = OAKGetByte(OTI87_MODESELECT);	regs[OTI87_FEATURE_DATA] = OAKGetByte(OTI87_FEATURE_DATA);	regs[OTI87_XREADSEGMENT_DATA] = OAKGetByte(OTI87_XREADSEGMENT);	regs[OTI87_XWRITESEGMENT_DATA] = OAKGetByte(OTI87_XWRITESEGMENT);    }    return 19;			/*19 additional registers */}/* oak_setregs( const unsigned char regs[], int mode )  Set Oak registers * Set extended registers for specified graphics mode * regs [EXT+1] through [EXT+7] used for OTI-067/77 * regs [EXT+9] through [EXT+17] used for OTI-087 native mode */static void oak_setregs(const unsigned char regs[], int mode){    int junk;    oak_unlock();    if (oak_chiptype == 87) {	OAKSetByte(OTI87_XREADSEGMENT, regs[OTI87_XREADSEGMENT_DATA]);	OAKSetByte(OTI87_XWRITESEGMENT, regs[OTI87_XWRITESEGMENT_DATA]);	outb(SEQ_I, 0);		/* reset sync. */	junk = inb(SEQ_D);	outw(SEQ_I, 0x00 + ((junk & 0xfd) << 8));	OAKSetByte(OTI87_CLOCK, regs[EXT + 8]);	OAKSetByte(OTI87_FIFO, regs[OTI87_FIFO_DATA]);	OAKSetByte(OTI87_MODESELECT, regs[OTI87_MODESELECT_DATA]);	outw(SEQ_I, 0x00 + (junk << 8));	/* set sync. */	OAKSetByte(OTI87_XCRTC, regs[OTI87_XCRTC_DATA]);	OAKSetByte(OTI87_OVERFLOW, regs[EXT + 9]);	OAKSetByte(OTI87_HSYNC2, regs[OTI87_HSYNC2_DATA]);	OAK_WriteDAC(regs[OTI87_RAMDAC_DATA]);    } else {	OAKSetByte(OTI_SEGMENT, regs[OTI_SEGMENT_DATA]);	/* doc says don't OTI-MISC unless sync. reset is off */	outb(SEQ_I, 0);	junk = inb(SEQ_D);	outw(SEQ_I, 0x00 + ((junk & 0xFD) << 8));	/* now disable the timing sequencer */	OAKSetByte(OTI_MISC, regs[OTI_MISC_DATA]);	/* put sequencer back */	outw(SEQ_I, 0x00 + (junk << 8));	OAKSetByte(OTI_BCOMPAT, regs[OTI_BCOMPAT_DATA]);	OAKSetByte(OTI_CONFIG, regs[OTI_CONFIG_DATA]);	OAKSetByte(OTI_OVERFLOW, regs[OTI_OVERFLOW_DATA]);	OAKSetByte(OTI87_HSYNC2, regs[OTI_HSYNC2_DATA]);	OAKSetByte(OTI_OVERFLOW2, regs[OTI_OVERFLOW2_DATA]);    }}/* oak_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 oak_modeavailable(int mode){    const unsigned char *regs;    struct info *info;    regs = LOOKUPMODE(oak_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 (oak_memory * 1024 < info->ydim * info->xbytes) {	return 0;    }    return SVGADRV;}/* oak_interlaced( int mode )                           Is mode interlaced? * Self-explanatory. * Returns non-zero if mode is interlaced (bit 7) */static int oak_interlaced(int mode){    const unsigned char *regs;    if (oak_modeavailable(mode) != SVGADRV) {	return 0;    } else {	regs = LOOKUPMODE(oak_modes, mode);	if (regs == NULL || regs == DISABLE_MODE) {	    return 0;	} else {	    return regs[EXT + 05] & 0x80;	}    }}/* oak_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 oak_setmode(int mode, int prv_mode){    const unsigned char *rp;    unsigned char regs[sizeof(g640x480x256_regs)];    if ((oak_chiptype == 87) & (OTI87_OK_LINEAR == 1)) {	oak_clearlinearmode();    }    rp = LOOKUPMODE(oak_modes, mode);    if (rp == NULL || mode == GPLANE16)	return (int) (__svgalib_vga_driverspecs.setmode(mode, prv_mode));    if (!oak_modeavailable(mode))	return 1;		/* mode not available */    /* Update the register information */    memcpy(regs, rp, sizeof(regs));    /*  Number of memory chips */    if (oak_chiptype != 87) {	regs[OTI_MISC_DATA] &= 0x3F;	regs[OTI_MISC_DATA] |= (oak_memory == 1024 ? 0x40 : 0x00);	regs[OTI_MISC_DATA] |= (oak_memory >= 512 ? 0x80 : 0x00);	if (oak_chiptype == 77) {	    regs[OTI_CONFIG_DATA] |= 0x08;	} else {	    regs[OTI_CONFIG_DATA] &= 0xF7;	}    } else {			/* oak_chiptype == 87 */	if (mode == G640x480x256) {	    /* Oak-87 needs this bit, Oak-67 does not stand it - MW */	    regs[SEQ + 1] |= 0x8;	}    }    if (__svgalib_infotable[mode].colors == 16) {	/* switch from 256 to 16 color mode (from XFree86) */	regs[SEQ + 4] &= 0xf7;	/* Switch off chain 4 mode */	if (oak_chiptype == 87) {	    regs[OTI87_FIFO_DATA] &= 0xf0;	    regs[OTI87_MODESELECT_DATA] &= 0xf3;	} else {	    regs[OTI_MISC_DATA] &= 0xf0;	    regs[OTI_MISC_DATA] |= 0x18;	}    }    __svgalib_setregs(regs);    oak_setregs(regs, mode);    if ((oak_chiptype == 87) & (OTI87_OK_LINEAR == 1)) {	oak_setlinearmode();    }    return 0;}/* oak_unlock()                                         Unlock Oak registers * Enable register changes *  * _No effect with OTI-087 -- register is nonfunctional_ */static void oak_unlock(void)

⌨️ 快捷键说明

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