📄 vesa.c
字号:
/**/#include <stdlib.h>#include <stdio.h> /* for printf */#include <string.h> /* for memset */#include <unistd.h>#include <sys/mman.h> /* for mmap */#include "vga.h"#include "libvga.h"#include "driver.h"/* New style driver interface. */#include "timing.h"#include "vgaregs.h"#include "interface.h"#include "accel.h"#include "lrmi.h"#include "vbe.h"#define VESAREG_SAVE(i) (VGA_TOTAL_REGS+i)#define VESA_TOTAL_REGS (VGA_TOTAL_REGS + 4024)/* #define VESA_savebitmap 0x0e */int __svgalib_VESA_savebitmap=0x0e;int __svgalib_VESA_textmode=3;static int vesa_init(int, int, int);static void vesa_unlock(void);static int vesa_memory,vesa_chiptype;static int vesa_is_linear, vesa_logical_width, vesa_bpp, vesa_granularity;static int vesa_regs_size, vesa_linear_base, vesa_last_mode_set;static struct LRMI_regs vesa_r;static int vesa_read_write, vesa_read_window, vesa_write_window;static void * LRMI_mem1;static CardSpecs *cardspecs;static struct { struct vbe_info_block *info; struct vbe_mode_info_block *mode; } vesa_data;static int SVGALIB_VESA[__GLASTMODE+1];static int lrmi_inited=0;static void vesa_setpage(int page){vesa_r.eax=0x4f05;vesa_r.ebx=0;vesa_r.edx=page*64/vesa_granularity;__svgalib_LRMI_int(0x10,&vesa_r);if(vesa_read_write){ vesa_r.eax=0x4f05; vesa_r.ebx=1; vesa_r.edx=page*64/vesa_granularity; __svgalib_LRMI_int(0x10,&vesa_r);};}static int __svgalib_vesa_inlinearmode(void){return vesa_is_linear;}/* Fill in chipset specific mode information */static void vesa_getmodeinfo(int mode, vga_modeinfo *modeinfo){ if ((mode < G640x480x256 ) || mode == G720x348x2) return __svgalib_vga_driverspecs.getmodeinfo(mode, modeinfo); if(modeinfo->colors==16)return; modeinfo->maxpixels = vesa_memory*1024/modeinfo->bytesperpixel; modeinfo->maxlogicalwidth = 4088; /* just a guess, */ modeinfo->startaddressrange = vesa_memory * 1024 - 1; modeinfo->haveblit = 0; modeinfo->flags &= ~HAVE_RWPAGE; modeinfo->flags |= vesa_read_write; /* sets HAVE_RWPAGE bit */ /* for linear need VBE2 */ if(vesa_chiptype>=1) if (modeinfo->bytesperpixel >= 1) { modeinfo->flags |= CAPABLE_LINEAR; if (__svgalib_vesa_inlinearmode()) modeinfo->flags |= IS_LINEAR; } /* to get the logical scanline width */ memset(&vesa_r, 0, sizeof(vesa_r)); vesa_r.eax = 0x4f01; vesa_r.ecx = SVGALIB_VESA[mode]; vesa_r.es = (unsigned int)vesa_data.mode >> 4; vesa_r.edi = (unsigned int)vesa_data.mode & 0xf; if (!__svgalib_LRMI_int(0x10, &vesa_r)) { fprintf(stderr, "Can't get mode info (vm86 failure)\n"); return; } modeinfo->linewidth = vesa_data.mode->bytes_per_scanline;}/* Read and save chipset-specific registers */static int vesa_saveregs(unsigned char regs[]){ void * buf; buf=LRMI_mem1; vesa_r.eax=0x4f04; vesa_r.ebx=0; vesa_r.es=((long)buf)>>4; vesa_r.edx=1; vesa_r.ecx=__svgalib_VESA_savebitmap; __svgalib_LRMI_int(0x10,&vesa_r); memcpy(®s[VGA_TOTAL_REGS],buf,vesa_regs_size); return vesa_regs_size;}/* Set chipset-specific registers */static void vesa_setregs(const unsigned char regs[], int mode){ void * buf; buf=LRMI_mem1; memcpy(buf,®s[VGA_TOTAL_REGS],vesa_regs_size); vesa_r.eax=0x4f04; vesa_r.ebx=0; vesa_r.es=((long)buf)>>4; vesa_r.edx=2; vesa_r.ecx=__svgalib_VESA_savebitmap; __svgalib_LRMI_int(0x10,&vesa_r);}/* Return nonzero if mode is available */static int vesa_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]; 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 SVGALIB_VESA[mode];}static int vesa_setmode(int mode, int prv_mode){ vesa_bpp=1; vesa_granularity=1; if ((mode < G640x480x256)|| (mode == G720x348x2)) { if(__svgalib_vesatext){ vesa_r.eax=0x4f02; /* make sure we are in a regular VGA mode before we start */ vesa_r.ebx=__svgalib_VESA_textmode; /* without this, if we start in SVGA mode the result might */ __svgalib_LRMI_int(0x10,&vesa_r); /* be something weird */ }; return __svgalib_vga_driverspecs.setmode(mode, prv_mode); } if (!vesa_modeavailable(mode)) return 1; vesa_r.eax=0x4f02; vesa_r.ebx=SVGALIB_VESA[mode]|0x8000|(vesa_is_linear*0x4000); vesa_last_mode_set=vesa_r.ebx; __svgalib_LRMI_int(0x10,&vesa_r); vesa_r.eax = 0x4f01; vesa_r.ecx=SVGALIB_VESA[mode]; vesa_r.es = (unsigned int)vesa_data.mode >> 4; vesa_r.edi = (unsigned int)vesa_data.mode&0xf; __svgalib_LRMI_int(0x10, &vesa_r); vesa_logical_width=vesa_data.mode->bytes_per_scanline; vesa_bpp=(vesa_data.mode->bits_per_pixel+7)/8; if(vesa_logical_width==0) vesa_logical_width=vesa_bpp*vesa_data.mode->x_resolution; /* if not reported then guess */ vesa_granularity=vesa_data.mode->win_granularity; if(vesa_granularity==0)vesa_granularity=64; /* if not reported then guess */ if(vesa_chiptype>=1)vesa_linear_base=vesa_data.mode->phys_base_ptr; vesa_read_write=0; vesa_read_window=0; vesa_write_window=0; if((vesa_data.mode->win_a_attributes&6)!=6){ vesa_read_write=1; if ((vesa_data.mode->win_b_attributes&2) == 2) vesa_read_window=1; if ((vesa_data.mode->win_b_attributes&4) == 4) vesa_write_window=1; } return 0;}/* Unlock chipset-specific registers */static void vesa_unlock(void){}/* Relock chipset-specific registers *//* (currently not used) */static void vesa_lock(void){}/* Indentify chipset, initialize and return non-zero if detected */static int vesa_test(void){ if ((getenv("IOPERM") == NULL) && ((iopl(3) < 0)||(ioperm(0,0x400,1)<0))) { printf("svgalib(vesa): Cannot get I/O permissions.\n"); exit(-1); } lrmi_inited=1; __svgalib_LRMI_init(); vesa_data.info = __svgalib_LRMI_alloc_real(sizeof(struct vbe_info_block) + sizeof(struct vbe_mode_info_block)); vesa_data.mode = (struct vbe_mode_info_block *)(vesa_data.info + 1); vesa_r.eax = 0x4f00; vesa_r.es = (unsigned int)vesa_data.info >> 4; vesa_r.edi = 0; __svgalib_LRMI_int(0x10, &vesa_r); if (vesa_r.eax!=0x4f) return 0; return !vesa_init(0,0,0);}/* No r/w paging */static void vesa_setrdpage(int page){vesa_r.eax=0x4f05;vesa_r.ebx=vesa_read_window;vesa_r.edx=page*64/vesa_granularity;__svgalib_LRMI_int(0x10,&vesa_r);}static void vesa_setwrpage(int page){vesa_r.eax=0x4f05;vesa_r.ebx=vesa_write_window;vesa_r.edx=page*64/vesa_granularity;__svgalib_LRMI_int(0x10,&vesa_r);}/* Set display start address (not for 16 color modes) */static void vesa_setdisplaystart(int address){ vesa_r.eax=0x4f07; vesa_r.ebx=0; vesa_r.ecx=address % vesa_logical_width; vesa_r.edx=address / vesa_logical_width; __svgalib_LRMI_int(0x10,&vesa_r);}/* Set logical scanline length (usually multiple of 8) */static void vesa_setlogicalwidth(int width){ vesa_r.eax=0x4f06; vesa_r.ebx=0; vesa_r.ecx=width / vesa_bpp ; __svgalib_LRMI_int(0x10,&vesa_r); vesa_logical_width=vesa_r.ebx;}static int vesa_linear(int op, int param){if (op==LINEAR_ENABLE) { vesa_r.eax=0x4f02;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -