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

📄 vga16.c

📁 //结构 struct fb_fix_screeninfo finfo struct fb_var_screeninfo vinfo //打开设备 fd = open[
💻 C
字号:
/* File: vga16.c */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <endian.h>#include <unistd.h>#include <fcntl.h>#include <termios.h>#include <signal.h>#include <errno.h>#include <signal.h>#include <limits.h>#include <sys/types.h>#include <sys/ioctl.h>#include <sys/mman.h>#include <sys/wait.h>#include <sys/stat.h>#include <sys/io.h>#include <linux/fb.h>#include <asm/io.h>#include <asm/system.h>//globalsstatic unsigned char *fb_mem;static int fb_line_length;static int fb_smem_length;static int fb_smem_offset;#define GRAPHICS_ADDR_REG 0x3ce         /* Graphics address register. */#define GRAPHICS_DATA_REG 0x3cf         /* Graphics data register. */#define SET_RESET_INDEX 0               /* Set/Reset Register index. */#define ENABLE_SET_RESET_INDEX 1        /* Enable Set/Reset Register index. */#define DATA_ROTATE_INDEX 3             /* Data Rotate Register index. */#define GRAPHICS_MODE_INDEX 5           /* Graphics Mode Register index. */#define BIT_MASK_INDEX 8                /* Bit Mask Register index. */#define __OUT1_U(s,x) \static void out##s(unsigned x value, unsigned short port) {#define __OUT2_U(s,s1,s2) \__asm__ __volatile__ ("out" #s " %" s1 "0,%" s2 "1"#define __OUT_U(s,s1,x) \__OUT1_U(s,x) __OUT2_U(s,s1,"w") : : "a" (value), "Nd" (port)); } \__OUT1_U(s##_p,x) __OUT2_U(s,s1,"w") __FULL_SLOW_DOWN_IO : : "a" (value), "Nd" (port));} \#define __IN1_U(s) \static RETURN_TYPE in##s(unsigned short port) { RETURN_TYPE _v;#define __IN2_U(s,s1,s2) \__asm__ __volatile__ ("in" #s " %" s2 "1,%" s1 "0"#define __IN_U(s,s1,i...) \__IN1_U(s) __IN2_U(s,s1,"w") : "=a" (_v) : "Nd" (port) ,##i ); return _v; } \__IN1_U(s##_p) __IN2_U(s,s1,"w") __FULL_SLOW_DOWN_IO : "=a" (_v) : "Nd" (port) ,##i ); return _v; } \#define __INS_U(s) \static void ins##s(unsigned short port, void * addr, unsigned long count) \{ __asm__ __volatile__ ("cld ; rep ; ins" #s \: "=D" (addr), "=c" (count) : "d" (port),"0" (addr),"1" (count)); }#define __OUTS_U(s) \static void outs##s(unsigned short port, const void * addr, unsigned long count) \{ __asm__ __volatile__ ("cld ; rep ; outs" #s \: "=S" (addr), "=c" (count) : "d" (port),"0" (addr),"1" (count)); }__OUT_U(b,"b", char)__OUT_U(w,"w", short)__OUT_U(l,, int)/* The VGA's weird architecture often requires that we read a byte and   write a byte to the same location.  It doesn't matter *what* byte   we write, however.  This is because all the action goes on behind   the scenes in the VGA's 32-bit latch register, and reading and writing   video memory just invokes latch behavior.   To avoid race conditions (is this necessary?), reading and writing   the memory byte should be done with a single instruction.  One   suitable instruction is the x86 bitwise OR.  The following   read-modify-write routine should optimize to one such bitwise   OR. */static inline void rmw(volatile char *p){        *p |= 1;}/* Set the Graphics Mode Register.  Bits 0-1 are write mode, bit 3 is   read mode. */static inline void setmode(int mode){        outb(GRAPHICS_MODE_INDEX, GRAPHICS_ADDR_REG);        outb(mode, GRAPHICS_DATA_REG);}/* Select the Bit Mask Register. */static inline void selectmask(void){        outb(BIT_MASK_INDEX, GRAPHICS_ADDR_REG);}/* Set the value of the Bit Mask Register.  It must already have been   selected with selectmask(). */static inline void setmask(int mask){        outb(mask, GRAPHICS_DATA_REG);}/* Set the Data Rotate Register.  Bits 0-2 are rotate count, bits 3-4   are logical operation (0=NOP, 1=AND, 2=OR, 3=XOR). */static inline void setop(int op){        outb(DATA_ROTATE_INDEX, GRAPHICS_ADDR_REG);        outb(op, GRAPHICS_DATA_REG);}/* Set the Enable Set/Reset Register.  The code here always uses value   0xf for this register.  */static inline void setsr(int sr){        outb(ENABLE_SET_RESET_INDEX, GRAPHICS_ADDR_REG);        outb(sr, GRAPHICS_DATA_REG);}/* Set the Set/Reset Register. */static inline void setcolor(int color){        outb(SET_RESET_INDEX, GRAPHICS_ADDR_REG);        outb(color, GRAPHICS_DATA_REG);}/* Set the value in the Graphics Address Register. */static inline void setindex(int index){        outb(index, GRAPHICS_ADDR_REG);}int  vga16_init(int fd,  	struct fb_fix_screeninfo *finfo, struct fb_var_screeninfo *vinfo){	static size_t map_amt;	if(ioperm(0x3c0, 0x20, 1) == -1){		printf("Cannot init vga16 mode.\n");		exit(1);	}	//assign globals	fb_line_length = finfo->line_length;	fb_smem_length = finfo->smem_len;	fb_smem_offset = 0;	map_amt = 0x10000;	map_amt = (map_amt + getpagesize() -1 )/ getpagesize() * getpagesize();	fb_mem = mmap(NULL, map_amt, PROT_READ | PROT_WRITE, 		MAP_SHARED, fd, 0);	if(!fb_mem || fb_mem == (unsigned char *)-1){		printf("Error init...\n");		exit(1);	}	return 0;}void vga16_clear(){	memset(fb_mem, 0, fb_smem_length);}void vga16_set_pixel(int x, int y, unsigned long c){	volatile char *where;	setmode(0);	setop(0);	setcolor(c);	selectmask();	setmask(0x80 >> (x % 8));	where = fb_mem + y * 80 + x/8;	rmw(where);}void vga16_rectangle(int x1, int y1, int x2, int y2, int color){	int i, j;	for(i=x1; i<x2; i++)	for(j=x1; j<x2; j++)		vga16_set_pixel(i, j, color);}void vga16_putc(unsigned char *cdat, int yy, int xx, int fg, int bg){        int y;        char *where = fb_mem + xx/8 + yy * fb_line_length;        setmode(2);        setop(0);        setsr(0xf);        setcolor(fg);        selectmask();        setmask(0xff);        *where = bg;        rmb();        *(volatile char*)where; /* fill latches */        setmode(3);        wmb();        *(volatile char*)where; /* fill latches */        setmode(3);        wmb();        for (y = 0; y < 16; y++, where += fb_line_length)                *where = cdat[y];        wmb();}static inline void set_read_plane (int plane){        outb (4, 0x3ce);        outb (plane, 0x3cf);}int vga16_read_pixel(int x,int y){        volatile char * src;        int             plane;        int             c = 0;        src = fb_mem + x / 8 + y * fb_line_length;        for(plane=0; plane<4; ++plane) {                set_read_plane(plane);                if(*src & (0x80 >> (x % 8)))                        c |= 1 << plane;        }        return c;}

⌨️ 快捷键说明

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