diff options
author | arpi <arpi@b3059339-0415-0410-9bf9-f77b7e298cf2> | 2003-02-09 20:18:23 +0000 |
---|---|---|
committer | arpi <arpi@b3059339-0415-0410-9bf9-f77b7e298cf2> | 2003-02-09 20:18:23 +0000 |
commit | 7ff83a71810233276517bc497e93ac15267bc830 (patch) | |
tree | 23e697fbbe48eae893b8c28c383199bc6ca000ad /linux | |
parent | c98692a0bf56e79781ae7ca2a1e358f518838dac (diff) | |
download | mpv-7ff83a71810233276517bc497e93ac15267bc830.tar.bz2 mpv-7ff83a71810233276517bc497e93ac15267bc830.tar.xz |
linux->osdep
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@9381 b3059339-0415-0410-9bf9-f77b7e298cf2
Diffstat (limited to 'linux')
-rw-r--r-- | linux/.cvsignore | 1 | ||||
-rw-r--r-- | linux/Makefile | 46 | ||||
-rw-r--r-- | linux/getch2.c | 256 | ||||
-rw-r--r-- | linux/getch2.h | 20 | ||||
-rw-r--r-- | linux/keycodes.h | 36 | ||||
-rw-r--r-- | linux/lrmi.c | 912 | ||||
-rw-r--r-- | linux/lrmi.h | 86 | ||||
-rw-r--r-- | linux/scandir.c | 134 | ||||
-rw-r--r-- | linux/shmem.c | 107 | ||||
-rw-r--r-- | linux/shmem.h | 4 | ||||
-rw-r--r-- | linux/strsep.c | 42 | ||||
-rw-r--r-- | linux/timer-lx.c | 67 | ||||
-rw-r--r-- | linux/timer.h | 17 | ||||
-rw-r--r-- | linux/vbelib.c | 730 | ||||
-rw-r--r-- | linux/vbelib.h | 227 | ||||
-rw-r--r-- | linux/vsscanf.c | 20 |
16 files changed, 0 insertions, 2705 deletions
diff --git a/linux/.cvsignore b/linux/.cvsignore deleted file mode 100644 index 4671378aef..0000000000 --- a/linux/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -.depend diff --git a/linux/Makefile b/linux/Makefile deleted file mode 100644 index f42b913d07..0000000000 --- a/linux/Makefile +++ /dev/null @@ -1,46 +0,0 @@ - -include ../config.mak - -LIBNAME = libosdep.a - -SRCS=getch2.c timer-lx.c shmem.c strsep.c vsscanf.c scandir.c # timer.c -OBJS=$(SRCS:.c=.o) - -ifeq ($(TARGET_ARCH_X86),yes) -ifeq ($(TARGET_OS),Linux) -SRCS += lrmi.c vbelib.c -endif -endif - -CFLAGS = $(OPTFLAGS) -I. -I.. $(EXTRA_INC) -# -I/usr/X11R6/include/ - -.SUFFIXES: .c .o - -# .PHONY: all clean - -.c.o: - $(CC) -c $(CFLAGS) -o $@ $< - -$(LIBNAME): $(OBJS) - $(AR) r $(LIBNAME) $(OBJS) - -all: $(LIBNAME) - -clean: - rm -f *.o *.a *~ - -distclean: - rm -f Makefile.bak *.o *.a *~ .depend - -dep: depend - -depend: - $(CC) -MM $(CFLAGS) $(SRCS) 1>.depend - -# -# include dependency files if they exist -# -ifneq ($(wildcard .depend),) -include .depend -endif diff --git a/linux/getch2.c b/linux/getch2.c deleted file mode 100644 index dec9b91a0f..0000000000 --- a/linux/getch2.c +++ /dev/null @@ -1,256 +0,0 @@ -/* GyS-TermIO v2.0 (for GySmail v3) (C) 1999 A'rpi/ESP-team */ - -#include "../config.h" - -//#define USE_TERMCAP -#ifndef __OS2__ -#define USE_IOCTL -#endif - -#define MAX_KEYS 64 -#define BUF_LEN 256 - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/time.h> -#include <sys/types.h> -#ifdef USE_IOCTL -#include <sys/ioctl.h> -#endif - -#ifdef HAVE_TERMIOS -#ifdef HAVE_TERMIOS_H -#include <termios.h> -#endif -#ifdef HAVE_SYS_TERMIOS_H -#include <sys/termios.h> -#endif -#endif - -#include <unistd.h> - -#include "keycodes.h" - -#ifdef HAVE_TERMIOS -static struct termios tio_orig; -#endif -static int getch2_len=0; -static char getch2_buf[BUF_LEN]; - -int screen_width=80; -int screen_height=24; - -typedef struct { - int len; - int code; - char chars[8]; -} keycode_st; -static keycode_st getch2_keys[MAX_KEYS]; -static int getch2_key_db=0; - -#ifdef USE_TERMCAP - -#if 0 -#include <termcap.h> -#else - extern int tgetent (char *BUFFER, char *TERMTYPE); - extern int tgetnum (char *NAME); - extern int tgetflag (char *NAME); - extern char *tgetstr (char *NAME, char **AREA); -#endif - -static char term_buffer[4096]; -static char term_buffer2[4096]; -static char *term_p=term_buffer2; - -static void termcap_add(char *id,int code){ -char *p=tgetstr(id,&term_p); - if(!p) return; - if(getch2_key_db>=MAX_KEYS) return; - getch2_keys[getch2_key_db].len=strlen(p); - strncpy(getch2_keys[getch2_key_db].chars,p,8); - getch2_keys[getch2_key_db].code=code; - ++getch2_key_db; -/* printf("%s=%s\n",id,p); */ -} - -static int success=0; - -int load_termcap(char *termtype){ - if(!termtype) termtype=getenv("TERM"); - if(!termtype) termtype="unknown"; - success=tgetent(term_buffer, termtype); - if(success<0){ printf("Could not access the 'termcap' data base.\n"); return 0; } - if(success==0){ printf("Terminal type `%s' is not defined.\n", termtype);return 0;} - - screen_width=tgetnum("co"); - screen_height=tgetnum("li"); - if(screen_width<1 || screen_width>255) screen_width=80; - if(screen_height<1 || screen_height>255) screen_height=24; - - termcap_add("kP",KEY_PGUP); - termcap_add("kN",KEY_PGDWN); - termcap_add("kh",KEY_HOME); - termcap_add("kH",KEY_END); - termcap_add("kI",KEY_INS); - termcap_add("kD",KEY_DEL); - termcap_add("kb",KEY_BS); - termcap_add("kl",KEY_LEFT); - termcap_add("kd",KEY_DOWN); - termcap_add("ku",KEY_UP); - termcap_add("kr",KEY_RIGHT); - termcap_add("k0",KEY_F+0); - termcap_add("k1",KEY_F+1); - termcap_add("k2",KEY_F+2); - termcap_add("k3",KEY_F+3); - termcap_add("k4",KEY_F+4); - termcap_add("k5",KEY_F+5); - termcap_add("k6",KEY_F+6); - termcap_add("k7",KEY_F+7); - termcap_add("k8",KEY_F+8); - termcap_add("k9",KEY_F+9); - termcap_add("k;",KEY_F+10); - return getch2_key_db; -} - -#endif - -void get_screen_size(){ -#ifdef USE_IOCTL - struct winsize ws; - if (ioctl(0, TIOCGWINSZ, &ws) < 0 || !ws.ws_row || !ws.ws_col) return; -/* printf("Using IOCTL\n"); */ - screen_width=ws.ws_col; - screen_height=ws.ws_row; -#endif -} - -int getch2(int time){ - int len=0; - int code=0; - int i=0; - - while(!getch2_len || (getch2_len==1 && getch2_buf[0]==27)){ - fd_set rfds; - struct timeval tv; - int retval; - /* Watch stdin (fd 0) to see when it has input. */ - FD_ZERO(&rfds); FD_SET(0,&rfds); - /* Wait up to 'time' microseconds. */ - tv.tv_sec=time/1000; tv.tv_usec = (time%1000)*1000; - retval=select(1, &rfds, NULL, NULL, &tv); - if(retval<=0) return -1; - /* Data is available now. */ - retval=read(0,&getch2_buf[getch2_len],BUF_LEN-getch2_len); - if(retval<1) return -1; - getch2_len+=retval; - } - - /* First find in the TERMCAP database: */ - for(i=0;i<getch2_key_db;i++){ - if((len=getch2_keys[i].len)<=getch2_len) - if(memcmp(getch2_keys[i].chars,getch2_buf,len)==0){ - code=getch2_keys[i].code; goto found; - } - } - len=1;code=getch2_buf[0]; - /* Check the well-known codes... */ - if(code!=27){ - if(code=='A'-64){ code=KEY_HOME; goto found;} - if(code=='E'-64){ code=KEY_END; goto found;} - if(code=='D'-64){ code=KEY_DEL; goto found;} - if(code=='H'-64){ code=KEY_BS; goto found;} - if(code=='U'-64){ code=KEY_PGUP; goto found;} - if(code=='V'-64){ code=KEY_PGDWN; goto found;} - if(code==8 || code==127){ code=KEY_BS; goto found;} - if(code==10 || code==13){ - if(getch2_len>1){ - int c=getch2_buf[1]; - if(c==10 || c==13) if(c!=code) len=2; - } - code=KEY_ENTER; - goto found; - } - } else if(getch2_len>1){ - int c=getch2_buf[1]; - if(c==27){ code=KEY_ESC; len=2; goto found;} - if(c>='0' && c<='9'){ code=c-'0'+KEY_F; len=2; goto found;} - if(getch2_len>=4 && c=='[' && getch2_buf[2]=='['){ - int c=getch2_buf[3]; - if(c>='A' && c<'A'+12){ code=KEY_F+1+c-'A';len=4;goto found;} - } - if(c=='[' || c=='O') if(getch2_len>=3){ - int c=getch2_buf[2]; - static short int ctable[]={ KEY_UP,KEY_DOWN,KEY_RIGHT,KEY_LEFT,0, - KEY_END,KEY_PGDWN,KEY_HOME,KEY_PGUP,0,0,KEY_INS,0,0,0, - KEY_F+1,KEY_F+2,KEY_F+3,KEY_F+4}; - if(c>='A' && c<='S') - if(ctable[c-'A']){ code=ctable[c-'A']; len=3; goto found;} - } - if(getch2_len>=4 && c=='[' && getch2_buf[3]=='~'){ - int c=getch2_buf[2]; - int ctable[8]={KEY_HOME,KEY_INS,KEY_DEL,KEY_END,KEY_PGUP,KEY_PGDWN,KEY_HOME,KEY_END}; - if(c>='1' && c<='8'){ code=ctable[c-'1']; len=4; goto found;} - } - if(getch2_len>=5 && c=='[' && getch2_buf[4]=='~'){ - int i=getch2_buf[2]-'0'; - int j=getch2_buf[3]-'0'; - if(i>=0 && i<=9 && j>=0 && j<=9){ - static short int ftable[20]={ - 11,12,13,14,15, 17,18,19,20,21, - 23,24,25,26,28, 29,31,32,33,34 }; - int a=i*10+j; - for(i=0;i<20;i++) if(ftable[i]==a){ code=KEY_F+1+i;len=5;goto found;} - } - } - } -found: - if((getch2_len-=len)>0){ - int i; - for(i=0;i<getch2_len;i++) getch2_buf[i]=getch2_buf[len+i]; - } - return code; -} - -static int getch2_status=0; - -void getch2_enable(){ -#ifdef HAVE_TERMIOS -struct termios tio_new; -#if defined(__NetBSD__) || defined(__svr4__) || defined(__CYGWIN__) || defined(__OS2__) || defined(__GNU__) - tcgetattr(0,&tio_orig); -#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__bsdi__) || defined(__APPLE__) - ioctl(0,TIOCGETA,&tio_orig); -#else - ioctl(0,TCGETS,&tio_orig); -#endif - tio_new=tio_orig; - tio_new.c_lflag &= ~(ICANON|ECHO); /* Clear ICANON and ECHO. */ - tio_new.c_cc[VMIN] = 1; - tio_new.c_cc[VTIME] = 0; -#if defined(__NetBSD__) || defined(__svr4__) || defined(__CYGWIN__) || defined(__OS2__) || defined(__GNU__) - tcsetattr(0,TCSANOW,&tio_new); -#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__bsdi__) || defined(__APPLE__) - ioctl(0,TIOCSETA,&tio_new); -#else - ioctl(0,TCSETS,&tio_new); -#endif -#endif - getch2_status=1; -} - -void getch2_disable(){ - if(!getch2_status) return; // already disabled / never enabled -#ifdef HAVE_TERMIOS -#if defined(__NetBSD__) || defined(__svr4__) || defined(__CYGWIN__) || defined(__OS2__) || defined(__GNU__) - tcsetattr(0,TCSANOW,&tio_orig); -#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__bsdi__) || defined(__APPLE__) - ioctl(0,TIOCSETA,&tio_orig); -#else - ioctl(0,TCSETS,&tio_orig); -#endif -#endif - getch2_status=0; -} - diff --git a/linux/getch2.h b/linux/getch2.h deleted file mode 100644 index 016de5ae9e..0000000000 --- a/linux/getch2.h +++ /dev/null @@ -1,20 +0,0 @@ -/* GyS-TermIO v2.0 (for GySmail v3) (C) 1999 A'rpi/ESP-team */ -/* a very small replacement of ncurses library */ - -/* Screen size. Initialized by load_termcap() and get_screen_size() */ -extern int screen_width; -extern int screen_height; - -/* Get screen-size using IOCTL call. */ -extern void get_screen_size(); - -/* Load key definitions from the TERMCAP database. 'termtype' can be NULL */ -extern int load_termcap(char *termtype); - -/* Enable and disable STDIN line-buffering */ -extern void getch2_enable(); -extern void getch2_disable(); - -/* Read a character or a special key code (see keycodes.h) */ -extern int getch2(int halfdelay_time); - diff --git a/linux/keycodes.h b/linux/keycodes.h deleted file mode 100644 index e0b963535c..0000000000 --- a/linux/keycodes.h +++ /dev/null @@ -1,36 +0,0 @@ -/* KEY code definitions for GyS-TermIO v2.0 (C) 1999 A'rpi/ESP-team */ - -#define KEY_ENTER 13 -#define KEY_TAB 9 - -#define KEY_BASE 0x100 - -/* Function keys */ -#define KEY_F (KEY_BASE+64) - -/* Control keys */ -#define KEY_CTRL (KEY_BASE) -#define KEY_BACKSPACE (KEY_CTRL+0) -#define KEY_DELETE (KEY_CTRL+1) -#define KEY_INSERT (KEY_CTRL+2) -#define KEY_HOME (KEY_CTRL+3) -#define KEY_END (KEY_CTRL+4) -#define KEY_PAGE_UP (KEY_CTRL+5) -#define KEY_PAGE_DOWN (KEY_CTRL+6) -#define KEY_ESC (KEY_CTRL+7) - -/* Control keys short name */ -#define KEY_BS KEY_BACKSPACE -#define KEY_DEL KEY_DELETE -#define KEY_INS KEY_INSERT -#define KEY_PGUP KEY_PAGE_UP -#define KEY_PGDOWN KEY_PAGE_DOWN -#define KEY_PGDWN KEY_PAGE_DOWN - -/* Cursor movement */ -#define KEY_CRSR (KEY_BASE+16) -#define KEY_RIGHT (KEY_CRSR+0) -#define KEY_LEFT (KEY_CRSR+1) -#define KEY_DOWN (KEY_CRSR+2) -#define KEY_UP (KEY_CRSR+3) - diff --git a/linux/lrmi.c b/linux/lrmi.c deleted file mode 100644 index ce77a6767a..0000000000 --- a/linux/lrmi.c +++ /dev/null @@ -1,912 +0,0 @@ -/* -Linux Real Mode Interface - A library of DPMI-like functions for Linux. - -Copyright (C) 1998 by Josh Vanderhoof - -You are free to distribute and modify this file, as long as you -do not remove this copyright notice and clearly label modified -versions as being modified. - -This software has NO WARRANTY. Use it at your own risk. -Original location: http://cvs.debian.org/lrmi/ -*/ - -#include <stdio.h> -#include <string.h> -#include <sys/io.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 0x100 - -struct 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 int -real_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 void -insert_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 void -delete_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; - } - - -void -LRMI_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 255 - -static struct - { - int ready; - unsigned short ret_seg, ret_off; - unsigned short stack_seg, stack_off; - struct vm86_struct vm; - } context = { 0 }; - - -static inline void -set_bit(unsigned int bit, void *array) - { - unsigned char *a = array; - - a[bit / 8] |= (1 << (bit % 8)); - } - - -static inline unsigned int -get_int_seg(int i) - { - return *(unsigned short *)(i * 4 + 2); - } - - -static inline unsigned int -get_int_off(int i) - { - return *(unsigned short *)(i * 4); - } - - -static inline void -pushw(unsigned short i) - { - struct vm86_regs *r = &context.vm.regs; - r->esp -= 2; - *(unsigned short *)(((unsigned int)r->ss << 4) + r->esp) = i; - } - - -int -LRMI_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)); - - /* - 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 void -set_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 void -get_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 void -em_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 void -em_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 void -em_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)); - } - else - { - if (size == 4) - asm volatile ("cld; outsl" - : "=S" (esi) : "d" (edx), "0" (esi)); - else if (size == 2) - asm volatile ("cld; outsw" - : "=S" (esi) : "d" (edx), "0" (esi)); - else - asm volatile ("cld; outsb" - : "=S" (esi) : "d" (edx), "0" (esi)); - } - - esi -= (unsigned int)context.vm.regs.ds << 4; - - context.vm.regs.esi &= 0xffff0000; - context.vm.regs.esi |= esi & 0xffff; - } - -static void -em_rep_outs(int size) - { - unsigned int ecx, edx, esi; - - ecx = context.vm.regs.ecx & 0xffff; - 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; rep; outsl; cld" - : "=S" (esi), "=c" (ecx) - : "d" (edx), "0" (esi), "1" (ecx)); - else if (size == 2) - asm volatile ("std; rep; outsw; cld" - : "=S" (esi), "=c" (ecx) - : "d" (edx), "0" (esi), "1" (ecx)); - else - asm volatile ("std; rep; outsb; cld" - : "=S" (esi), "=c" (ecx) - : "d" (edx), "0" (esi), "1" (ecx)); - } - else - { - if (size == 4) - asm volatile ("cld; rep; outsl" - : "=S" (esi), "=c" (ecx) - : "d" (edx), "0" (esi), "1" (ecx)); - else if (size == 2) - asm volatile ("cld; rep; outsw" - : "=S" (esi), "=c" (ecx) - : "d" (edx), "0" (esi), "1" (ecx)); - else - asm volatile ("cld; rep; outsb" - : "=S" (esi), "=c" (ecx) - : "d" (edx), "0" (esi), "1" (ecx)); - } - - esi -= (unsigned int)context.vm.regs.ds << 4; - - context.vm.regs.esi &= 0xffff0000; - context.vm.regs.esi |= esi & 0xffff; - - context.vm.regs.ecx &= 0xffff0000; - context.vm.regs.ecx |= ecx & 0xffff; - } - -static void -em_inbl(unsigned char literal) - { - context.vm.regs.eax = inb(literal) & 0xff; - } - -static void -em_inb(void) - { - asm volatile ("inb (%w1), %b0" - : "=a" (context.vm.regs.eax) - : "d" (context.vm.regs.edx), "0" (context.vm.regs.eax)); - } - -static void -em_inw(void) - { - asm volatile ("inw (%w1), %w0" - : "=a" (context.vm.regs.eax) - : "d" (context.vm.regs.edx), "0" (context.vm.regs.eax)); - } - -static void -em_inl(void) - { - asm volatile ("inl (%w1), %0" - : "=a" (context.vm.regs.eax) - : "d" (context.vm.regs.edx)); - } - -static void -em_outbl(unsigned char literal) - { - outb(context.vm.regs.eax & 0xff, literal); - } - -static void -em_outb(void) - { - asm volatile ("outb %b0, (%w1)" - : : "a" (context.vm.regs.eax), - "d" (context.vm.regs.edx)); - } - -static void -em_outw(void) - { - asm volatile ("outw %w0, (%w1)" - : : "a" (context.vm.regs.eax), - "d" (context.vm.regs.edx)); - } - -static void -em_outl(void) - { - asm volatile ("outl %0, (%w1)" - : : "a" (context.vm.regs.eax), - "d" (context.vm.regs.edx)); - } - -static int -emulate(void) - { - unsigned char *insn; - struct - { - unsigned int size : 1; - unsigned int rep : 1; - } prefix = { 0, 0 }; - int i = 0; - - insn = (unsigned char *)((unsigned int)context.vm.regs.cs << 4); - insn += context.vm.regs.eip; - - while (1) - { - if (insn[i] == 0x66) - { - prefix.size = 1 - prefix.size; - i++; - } - else if (insn[i] == 0xf3) - { - prefix.rep = 1; - i++; - } - else if (insn[i] == 0xf0 || insn[i] == 0xf2 - || insn[i] == 0x26 || insn[i] == 0x2e - || insn[i] == 0x36 || insn[i] == 0x3e - || insn[i] == 0x64 || insn[i] == 0x65 - || insn[i] == 0x67) - { - /* these prefixes are just ignored */ - i++; - } - else if (insn[i] == 0x6c) - { - if (prefix.rep) - em_rep_ins(1); - else - em_ins(1); - i++; - break; - } - else if (insn[i] == 0x6d) - { - if (prefix.rep) - { - if (prefix.size) - em_rep_ins(4); - else - em_rep_ins(2); - } - else - { - if (prefix.size) - em_ins(4); - else - em_ins(2); - } - i++; - break; - } - else if (insn[i] == 0x6e) - { - if (prefix.rep) - em_rep_outs(1); - else - em_outs(1); - i++; - break; - } - else if (insn[i] == 0x6f) - { - if (prefix.rep) - { - if (prefix.size) - em_rep_outs(4); - else - em_rep_outs(2); - } - else - { - if (prefix.size) - em_outs(4); - else - em_outs(2); - } - i++; - break; - } - else if (insn[i] == 0xe4) - { - em_inbl(insn[i + 1]); - i += 2; - break; - } - else if (insn[i] == 0xe6) - { - em_outbl(insn[i + 1]); - i += 2; - break; - } - else if (insn[i] == 0xec) - { - em_inb(); - i++; - break; - } - else if (insn[i] == 0xed) - { - if (prefix.size) - em_inl(); - else - em_inw(); - i++; - break; - } - else if (insn[i] == 0xee) - { - em_outb(); - i++; - break; - } - else if (insn[i] == 0xef) - { - if (prefix.size) - em_outl(); - else - em_outw(); - - i++; - break; - } - else - return 0; - } - - context.vm.regs.eip += i; - return 1; - } - - -/* - I don't know how to make sure I get the right vm86() from libc. - The one I want is syscall # 113 (vm86old() in libc 5, vm86() in glibc) - which should be declared as "int vm86(struct vm86_struct *);" in - <sys/vm86.h>. - - This just does syscall 113 with inline asm, which should work - for both libc's (I hope). -*/ -#if !defined(USE_LIBC_VM86) -static int -lrmi_vm86(struct vm86_struct *vm) - { - int r; -#ifdef __PIC__ - asm volatile ( - "pushl %%ebx\n\t" - "movl %2, %%ebx\n\t" - "int $0x80\n\t" - "popl %%ebx" - : "=a" (r) - : "0" (113), "r" (vm)); |