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

📄 lrmi.c

📁 linux 下svgalib编的一个界面程序示例
💻 C
📖 第 1 页 / 共 2 页
字号:
/*Linux Real Mode Interface - A library of DPMI-like functions for Linux.Copyright (C) 1998 by Josh VanderhoofYou are free to distribute and modify this file, as long as youdo not remove this copyright notice and clearly label modifiedversions as being modified.This software has NO WARRANTY.  Use it at your own risk.*/#include <stdio.h>#include <string.h>#include <asm/vm86.h>#ifdef USE_LIBC_VM86#include <sys/vm86.h>#endif#include <sys/types.h>#include <sys/stat.h>#include <sys/mman.h>#include <unistd.h>#include <fcntl.h>#include "lrmi.h"#define REAL_MEM_BASE 	((void *)0x10000)#define REAL_MEM_SIZE 	0x10000#define REAL_MEM_BLOCKS 	0x100struct mem_block	{	unsigned int size : 20;	unsigned int free : 1;	};static struct	{	int ready;	int count;	struct mem_block blocks[REAL_MEM_BLOCKS];	} mem_info = { 0 };static intreal_mem_init(void)	{	void *m;	int fd_zero;	if (mem_info.ready)		return 1;	fd_zero = open("/dev/zero", O_RDONLY);	if (fd_zero == -1)		{		perror("open /dev/zero");		return 0;		}	m = mmap((void *)REAL_MEM_BASE, REAL_MEM_SIZE,	 PROT_READ | PROT_WRITE | PROT_EXEC,	 MAP_FIXED | MAP_PRIVATE, fd_zero, 0);	if (m == (void *)-1)		{		perror("mmap /dev/zero");		close(fd_zero);		return 0;		}	mem_info.ready = 1;	mem_info.count = 1;	mem_info.blocks[0].size = REAL_MEM_SIZE;	mem_info.blocks[0].free = 1;	return 1;	}static voidinsert_block(int i)	{	memmove(	 mem_info.blocks + i + 1,	 mem_info.blocks + i,	 (mem_info.count - i) * sizeof(struct mem_block));	mem_info.count++;	}static voiddelete_block(int i)	{	mem_info.count--;	memmove(	 mem_info.blocks + i,	 mem_info.blocks + i + 1,	 (mem_info.count - i) * sizeof(struct mem_block));	}void *LRMI_alloc_real(int size)	{	int i;	char *r = (char *)REAL_MEM_BASE;	if (!mem_info.ready)		return NULL;	if (mem_info.count == REAL_MEM_BLOCKS)		return NULL;	size = (size + 15) & ~15;	for (i = 0; i < mem_info.count; i++)		{		if (mem_info.blocks[i].free && size < mem_info.blocks[i].size)			{			insert_block(i);			mem_info.blocks[i].size = size;			mem_info.blocks[i].free = 0;			mem_info.blocks[i + 1].size -= size;			return (void *)r;			}		r += mem_info.blocks[i].size;		}	return NULL;	}voidLRMI_free_real(void *m)	{	int i;	char *r = (char *)REAL_MEM_BASE;	if (!mem_info.ready)		return;	i = 0;	while (m != (void *)r)		{		r += mem_info.blocks[i].size;		i++;		if (i == mem_info.count)			return;		}	mem_info.blocks[i].free = 1;	if (i + 1 < mem_info.count && mem_info.blocks[i + 1].free)		{		mem_info.blocks[i].size += mem_info.blocks[i + 1].size;		delete_block(i + 1);		}	if (i - 1 >= 0 && mem_info.blocks[i - 1].free)		{		mem_info.blocks[i - 1].size += mem_info.blocks[i].size;		delete_block(i);		}	}#define DEFAULT_VM86_FLAGS 	(IF_MASK | IOPL_MASK)#define DEFAULT_STACK_SIZE 	0x1000#define RETURN_TO_32_INT 	255static struct	{	int ready;	unsigned short ret_seg, ret_off;	unsigned short stack_seg, stack_off;	struct vm86_struct vm;	} context = { 0 };static inline voidset_bit(unsigned int bit, void *array)	{	unsigned char *a = array;	a[bit / 8] |= (1 << (bit % 8));	}static inline unsigned intget_int_seg(int i)	{	return *(unsigned short *)(i * 4 + 2);	}static inline unsigned intget_int_off(int i)	{	return *(unsigned short *)(i * 4);	}static inline voidpushw(unsigned short i)	{	struct vm86_regs *r = &context.vm.regs;	r->esp -= 2;	*(unsigned short *)(((unsigned int)r->ss << 4) + r->esp) = i;	}intLRMI_init(void)	{	void *m;	int fd_mem;	if (context.ready)		return 1;	if (!real_mem_init())		return 0;	/*	 Map the Interrupt Vectors (0x0 - 0x400) + BIOS data (0x400 - 0x502)	 and the ROM (0xa0000 - 0x100000)	*/	fd_mem = open("/dev/mem", O_RDWR);	if (fd_mem == -1)		{		perror("open /dev/mem");		return 0;		}	m = mmap((void *)0, 0x502,	 PROT_READ | PROT_WRITE | PROT_EXEC,	 MAP_FIXED | MAP_PRIVATE, fd_mem, 0);	if (m == (void *)-1)		{		perror("mmap /dev/mem");		return 0;		}	m = mmap((void *)0xa0000, 0x100000 - 0xa0000,	 PROT_READ | PROT_WRITE,	 MAP_FIXED | MAP_SHARED, fd_mem, 0xa0000);	if (m == (void *)-1)		{		perror("mmap /dev/mem");		return 0;		}	/*	 Allocate a stack	*/	m = LRMI_alloc_real(DEFAULT_STACK_SIZE);	context.stack_seg = (unsigned int)m >> 4;	context.stack_off = DEFAULT_STACK_SIZE;	/*	 Allocate the return to 32 bit routine	*/	m = LRMI_alloc_real(2);	context.ret_seg = (unsigned int)m >> 4;	context.ret_off = (unsigned int)m & 0xf;	((unsigned char *)m)[0] = 0xcd; 	/* int opcode */	((unsigned char *)m)[1] = RETURN_TO_32_INT;	memset(&context.vm, 0, sizeof(context.vm));	context.vm.cpu_type =CPU_386;	/*	 Enable kernel emulation of all ints except RETURN_TO_32_INT	*/	memset(&context.vm.int_revectored, 0, sizeof(context.vm.int_revectored));	set_bit(RETURN_TO_32_INT, &context.vm.int_revectored);	context.ready = 1;	return 1;	}static voidset_regs(struct LRMI_regs *r)	{	context.vm.regs.edi = r->edi;	context.vm.regs.esi = r->esi;	context.vm.regs.ebp = r->ebp;	context.vm.regs.ebx = r->ebx;	context.vm.regs.edx = r->edx;	context.vm.regs.ecx = r->ecx;	context.vm.regs.eax = r->eax;	context.vm.regs.eflags = DEFAULT_VM86_FLAGS;	context.vm.regs.es = r->es;	context.vm.regs.ds = r->ds;	context.vm.regs.fs = r->fs;	context.vm.regs.gs = r->gs;	}static voidget_regs(struct LRMI_regs *r)	{	r->edi = context.vm.regs.edi;	r->esi = context.vm.regs.esi;	r->ebp = context.vm.regs.ebp;	r->ebx = context.vm.regs.ebx;	r->edx = context.vm.regs.edx;	r->ecx = context.vm.regs.ecx;	r->eax = context.vm.regs.eax;	r->flags = context.vm.regs.eflags;	r->es = context.vm.regs.es;	r->ds = context.vm.regs.ds;	r->fs = context.vm.regs.fs;	r->gs = context.vm.regs.gs;	}#define DIRECTION_FLAG 	(1 << 10)static voidem_ins(int size)	{	unsigned int edx, edi;	edx = context.vm.regs.edx & 0xffff;	edi = context.vm.regs.edi & 0xffff;	edi += (unsigned int)context.vm.regs.ds << 4;	if (context.vm.regs.eflags & DIRECTION_FLAG)		{		if (size == 4)			asm volatile ("std; insl; cld"			 : "=D" (edi) : "d" (edx), "0" (edi));		else if (size == 2)			asm volatile ("std; insw; cld"			 : "=D" (edi) : "d" (edx), "0" (edi));		else			asm volatile ("std; insb; cld"			 : "=D" (edi) : "d" (edx), "0" (edi));		}	else		{		if (size == 4)			asm volatile ("cld; insl"			 : "=D" (edi) : "d" (edx), "0" (edi));		else if (size == 2)			asm volatile ("cld; insw"			 : "=D" (edi) : "d" (edx), "0" (edi));		else			asm volatile ("cld; insb"			 : "=D" (edi) : "d" (edx), "0" (edi));		}	edi -= (unsigned int)context.vm.regs.ds << 4;	context.vm.regs.edi &= 0xffff0000;	context.vm.regs.edi |= edi & 0xffff;	}static voidem_rep_ins(int size)	{	unsigned int ecx, edx, edi;	ecx = context.vm.regs.ecx & 0xffff;	edx = context.vm.regs.edx & 0xffff;	edi = context.vm.regs.edi & 0xffff;	edi += (unsigned int)context.vm.regs.ds << 4;	if (context.vm.regs.eflags & DIRECTION_FLAG)		{		if (size == 4)			asm volatile ("std; rep; insl; cld"			 : "=D" (edi), "=c" (ecx)			 : "d" (edx), "0" (edi), "1" (ecx));		else if (size == 2)			asm volatile ("std; rep; insw; cld"			 : "=D" (edi), "=c" (ecx)			 : "d" (edx), "0" (edi), "1" (ecx));		else			asm volatile ("std; rep; insb; cld"			 : "=D" (edi), "=c" (ecx)			 : "d" (edx), "0" (edi), "1" (ecx));		}	else		{		if (size == 4)			asm volatile ("cld; rep; insl"			 : "=D" (edi), "=c" (ecx)			 : "d" (edx), "0" (edi), "1" (ecx));		else if (size == 2)			asm volatile ("cld; rep; insw"			 : "=D" (edi), "=c" (ecx)			 : "d" (edx), "0" (edi), "1" (ecx));		else			asm volatile ("cld; rep; insb"			 : "=D" (edi), "=c" (ecx)			 : "d" (edx), "0" (edi), "1" (ecx));		}	edi -= (unsigned int)context.vm.regs.ds << 4;	context.vm.regs.edi &= 0xffff0000;	context.vm.regs.edi |= edi & 0xffff;	context.vm.regs.ecx &= 0xffff0000;	context.vm.regs.ecx |= ecx & 0xffff;	}static voidem_outs(int size)	{	unsigned int edx, esi;	edx = context.vm.regs.edx & 0xffff;	esi = context.vm.regs.esi & 0xffff;	esi += (unsigned int)context.vm.regs.ds << 4;	if (context.vm.regs.eflags & DIRECTION_FLAG)		{		if (size == 4)			asm volatile ("std; outsl; cld"			 : "=S" (esi) : "d" (edx), "0" (esi));		else if (size == 2)			asm volatile ("std; outsw; cld"			 : "=S" (esi) : "d" (edx), "0" (esi));		else			asm volatile ("std; outsb; cld"			 : "=S" (esi) : "d" (edx), "0" (esi));

⌨️ 快捷键说明

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