diff -rc --new-file linux/include/linux/sched.h linux.new/include/linux/sched.h
*** linux/include/linux/sched.h	Sun Apr 17 21:42:24 1994
--- linux.new/include/linux/sched.h	Thu Apr 28 23:31:20 1994
***************
*** 213,220 ****
--- 219,228 ----
  	unsigned short used_math;
  	unsigned short rss;	/* number of resident pages */
  	char comm[16];
+ /* virtual 86 mode stuff */
  	struct vm86_struct * vm86_info;
  	unsigned long screen_bitmap;
+ 	unsigned long v86flags, v86mask, v86mode;
  /* file system info */
  	int link_count;
  	int tty;		/* -1 if no tty, so it must be signed */
***************
*** 280,286 ****
  /* math */	0, \
  /* rss */	2, \
  /* comm */	"swapper", \
! /* vm86_info */	NULL, 0, \
  /* fs info */	0,-1,0022,NULL,NULL,NULL,NULL, \
  /* ipc */	NULL, NULL, \
  /* filp */	{NULL,}, \
--- 288,294 ----
  /* math */	0, \
  /* rss */	2, \
  /* comm */	"swapper", \
! /* vm86_info */	NULL, 0, 0, 0, 0, \
  /* fs info */	0,-1,0022,NULL,NULL,NULL,NULL, \
  /* ipc */	NULL, NULL, \
  /* filp */	{NULL,}, \
diff -rc --new-file linux/include/linux/vm86.h linux.new/include/linux/vm86.h
*** linux/include/linux/vm86.h	Wed Dec  1 13:44:15 1993
--- linux.new/include/linux/vm86.h	Thu Apr 28 23:31:20 1994
***************
*** 1,7 ****
  #ifndef _LINUX_VM86_H
  #define _LINUX_VM86_H
  
! #define VM_MASK 0x00020000
  
  /*
   * This is the stack-layout when we have done a "SAVE_ALL" from vm86
--- 1,46 ----
  #ifndef _LINUX_VM86_H
  #define _LINUX_VM86_H
  
! /*
!  * I'm guessing at the VIF/VIP flag usage, but hope that this is how
!  * the Pentium uses them. Linux will return from vm86 mode when both
!  * VIF and VIP is set.
!  *
!  * On a Pentium, we could probably optimize the virtual flags directly
!  * in the eflags register instead of doing it "by hand" in vflags...
!  *
!  * Linus
!  */
! 
! #define TF_MASK		0x00000100
! #define IF_MASK		0x00000200
! #define IOPL_MASK	0x00003000
! #define NT_MASK		0x00004000
! #define VM_MASK		0x00020000
! #define AC_MASK		0x00040000
! #define VIF_MASK	0x00080000	/* virtual interrupt flag */
! #define VIP_MASK	0x00100000	/* virtual interrupt pending */
! #define ID_MASK		0x00200000
! 
! #define BIOSSEG		0x0f000
! 
! #define CPU_086		0
! #define CPU_186		1
! #define CPU_286		2
! #define CPU_386		3
! #define CPU_486		4
! #define CPU_586		5
! 
! /*
!  * Return values for the 'vm86()' system call
!  */
! #define VM86_TYPE(retval)	((retval) & 0xff)
! #define VM86_ARG(retval)	((retval) >> 8)
! 
! #define VM86_SIGNAL	0	/* return due to signal */
! #define VM86_UNKNOWN	1	/* unhandled GP fault - IO-instruction or similar */
! #define VM86_INTx	2	/* int3/int x instruction (ARG = x) */
! #define VM86_STI	3	/* sti/popf/iret instruction enabled virtual interrupts */
  
  /*
   * This is the stack-layout when we have done a "SAVE_ALL" from vm86
***************
*** 29,56 ****
  	long __null_gs;
  	long orig_eax;
  	long eip;
! 	long cs;
  	long eflags;
  	long esp;
! 	long ss;
  /*
   * these are specific to v86 mode:
   */
! 	long es;
! 	long ds;
! 	long fs;
! 	long gs;
  };
  
  struct vm86_struct {
  	struct vm86_regs regs;
  	unsigned long flags;
  	unsigned long screen_bitmap;
  };
  
  /*
   * flags masks
   */
! #define VM86_SCREEN_BITMAP 1
  
  #endif
--- 68,108 ----
  	long __null_gs;
  	long orig_eax;
  	long eip;
! 	unsigned short cs, __csh;
  	long eflags;
  	long esp;
! 	unsigned short ss, __ssh;
  /*
   * these are specific to v86 mode:
   */
! 	unsigned short es, __esh;
! 	unsigned short ds, __dsh;
! 	unsigned short fs, __fsh;
! 	unsigned short gs, __gsh;
! };
! 
! struct revectored_struct {
! 	unsigned long __map[8];			/* 256 bits */
  };
  
  struct vm86_struct {
  	struct vm86_regs regs;
  	unsigned long flags;
  	unsigned long screen_bitmap;
+ 	unsigned long cpu_type;
+ 	struct revectored_struct int_revectored;
+ 	struct revectored_struct int21_revectored;
  };
  
  /*
   * flags masks
   */
! #define VM86_SCREEN_BITMAP	0x0001
! 
! #ifdef __KERNEL__
! 
! void handle_vm86_fault(struct vm86_regs *, long);
! 
! #endif
  
  #endif
diff -rc --new-file linux/kernel/Makefile linux.new/kernel/Makefile
*** linux/kernel/Makefile	Fri Dec 17 07:14:28 1993
--- linux.new/kernel/Makefile	Thu Apr 21 19:02:05 1994
***************
*** 19,25 ****
  OBJS  = sched.o sys_call.o traps.o irq.o dma.o fork.o \
   	panic.o printk.o vsprintf.o sys.o module.o ksyms.o exit.o \
  	signal.o mktime.o ptrace.o ioport.o itimer.o \
! 	info.o ldt.o time.o
  
  all: kernel.o
  
--- 19,25 ----
  OBJS  = sched.o sys_call.o traps.o irq.o dma.o fork.o \
   	panic.o printk.o vsprintf.o sys.o module.o ksyms.o exit.o \
  	signal.o mktime.o ptrace.o ioport.o itimer.o \
! 	info.o ldt.o time.o vm86.o
  
  all: kernel.o
  
diff -rc --new-file linux/kernel/sys.c linux.new/kernel/sys.c
*** linux/kernel/sys.c	Sun Apr 17 21:42:12 1994
--- linux.new/kernel/sys.c	Thu Apr 28 23:31:20 1994
***************
*** 124,207 ****
  asmlinkage int sys_prof(void)
  {
  	return -ENOSYS;
- }
- 
- asmlinkage unsigned long save_v86_state(struct vm86_regs * regs)
- {
- 	unsigned long stack;
- 
- 	if (!current->vm86_info) {
- 		printk("no vm86_info: BAD\n");
- 		do_exit(SIGSEGV);
- 	}
- 	memcpy_tofs(&(current->vm86_info->regs),regs,sizeof(*regs));
- 	put_fs_long(current->screen_bitmap,&(current->vm86_info->screen_bitmap));
- 	stack = current->tss.esp0;
- 	current->tss.esp0 = current->saved_kernel_stack;
- 	current->saved_kernel_stack = 0;
- 	return stack;
- }
- 
- static void mark_screen_rdonly(struct task_struct * tsk)
- {
- 	unsigned long tmp;
- 	unsigned long *pg_table;
- 
- 	if ((tmp = tsk->tss.cr3) != 0) {
- 		tmp = *(unsigned long *) tmp;
- 		if (tmp & PAGE_PRESENT) {
- 			tmp &= PAGE_MASK;
- 			pg_table = (0xA0000 >> PAGE_SHIFT) + (unsigned long *) tmp;
- 			tmp = 32;
- 			while (tmp--) {
- 				if (PAGE_PRESENT & *pg_table)
- 					*pg_table &= ~PAGE_RW;
- 				pg_table++;
- 			}
- 		}
- 	}
- }
- 
- asmlinkage int sys_vm86(struct vm86_struct * v86)
- {
- 	struct vm86_struct info;
- 	struct pt_regs * pt_regs = (struct pt_regs *) &v86;
- 	int error;
- 
- 	if (current->saved_kernel_stack)
- 		return -EPERM;
- 	/* v86 must be readable (now) and writable (for save_v86_state) */
- 	error = verify_area(VERIFY_WRITE,v86,sizeof(*v86));
- 	if (error)
- 		return error;
- 	memcpy_fromfs(&info,v86,sizeof(info));
- /*
-  * make sure the vm86() system call doesn't try to do anything silly
-  */
- 	info.regs.__null_ds = 0;
- 	info.regs.__null_es = 0;
- 	info.regs.__null_fs = 0;
- 	info.regs.__null_gs = 0;
- /*
-  * The eflags register is also special: we cannot trust that the user
-  * has set it up safely, so this makes sure interrupt etc flags are
-  * inherited from protected mode.
-  */
- 	info.regs.eflags &= 0x00000dd5;
- 	info.regs.eflags |= ~0x00000dd5 & pt_regs->eflags;
- 	info.regs.eflags |= VM_MASK;
- 	current->saved_kernel_stack = current->tss.esp0;
- 	current->tss.esp0 = (unsigned long) pt_regs;
- 	current->vm86_info = v86;
- 	current->screen_bitmap = info.screen_bitmap;
- 	if (info.flags & VM86_SCREEN_BITMAP)
- 		mark_screen_rdonly(current);
- 	__asm__ __volatile__("movl %0,%%esp\n\t"
- 		"pushl $ret_from_sys_call\n\t"
- 		"ret"
- 		: /* no outputs */
- 		:"g" ((long) &(info.regs)),"a" (info.regs.eax));
- 	return 0;
  }
  
  extern void hard_reset_now(void);
--- 146,151 ----
diff -rc --new-file linux/kernel/traps.c linux.new/kernel/traps.c
*** linux/kernel/traps.c	Sun Apr 17 21:42:06 1994
--- linux.new/kernel/traps.c	Thu Apr 21 19:02:05 1994
***************
*** 125,133 ****
  DO_ERROR(10, SIGSEGV, "invalid TSS", invalid_TSS, current)
  DO_ERROR(11, SIGSEGV, "segment not present", segment_not_present, current)
  DO_ERROR(12, SIGSEGV, "stack segment", stack_segment, current)
- DO_ERROR(13, SIGSEGV, "general protection", general_protection, current)
  DO_ERROR(15, SIGSEGV, "reserved", reserved, current)
  DO_ERROR(17, SIGSEGV, "alignment check", alignment_check, current)
  
  asmlinkage void do_nmi(struct pt_regs * regs, long error_code)
  {
--- 125,144 ----
  DO_ERROR(10, SIGSEGV, "invalid TSS", invalid_TSS, current)
  DO_ERROR(11, SIGSEGV, "segment not present", segment_not_present, current)
  DO_ERROR(12, SIGSEGV, "stack segment", stack_segment, current)
  DO_ERROR(15, SIGSEGV, "reserved", reserved, current)
  DO_ERROR(17, SIGSEGV, "alignment check", alignment_check, current)
+ 
+ asmlinkage void do_general_protection(struct pt_regs * regs, long error_code)
+ {
+ 	if (regs->eflags & VM_MASK) {
+ 		handle_vm86_fault((struct vm86_regs *) regs, error_code);
+ 		return;
+ 	}
+ 	current->tss.error_code = error_code;
+ 	current->tss.trap_no = 13;
+ 	send_sig(SIGSEGV, current, 1);
+ 	die_if_kernel("general protection",regs,error_code);
+ }
  
  asmlinkage void do_nmi(struct pt_regs * regs, long error_code)
  {
diff -rc --new-file linux/kernel/vm86.c linux.new/kernel/vm86.c
*** linux/kernel/vm86.c	Thu Jan  1 01:00:00 1970
--- linux.new/kernel/vm86.c	Thu Apr 28 23:31:21 1994
***************
*** 0 ****
--- 1,370 ----
+ /*
+  *  linux/kernel/vm86.c
+  *
+  *  Copyright (C) 1994  Linus Torvalds
+  */
+ #include <linux/errno.h>
+ #include <linux/sched.h>
+ #include <linux/kernel.h>
+ #include <linux/signal.h>
+ #include <linux/string.h>
+ #include <linux/ptrace.h>
+ 
+ #include <asm/segment.h>
+ #include <asm/io.h>
+ 
+ /*
+  * 16-bit register defines..
+  */
+ #define IP(regs)	(*(unsigned short *)&((regs)->eip))
+ #define SP(regs)	(*(unsigned short *)&((regs)->esp))
+ 
+ /*
+  * virtual flags (16 and 32-bit versions)
+  */
+ #define VFLAGS	(*(unsigned short *)&(current->v86flags))
+ #define VEFLAGS	(current->v86flags)
+ 
+ #define set_flags(X,new,mask) \
+ ((X) = ((X) & ~(mask)) | ((new) & (mask)))
+ 
+ #define SAFE_MASK	(0xDD5)
+ #define RETURN_MASK	(0xDFF)
+ 
+ asmlinkage struct pt_regs * save_v86_state(struct vm86_regs * regs)
+ {
+ 	unsigned long tmp;
+ 
+ 	if (!current->vm86_info) {
+ 		printk("no vm86_info: BAD\n");
+ 		do_exit(SIGSEGV);
+ 	}
+ 	set_flags(regs->eflags, VEFLAGS, VIF_MASK | current->v86mask);
+ 	memcpy_tofs(&current->vm86_info->regs,regs,sizeof(*regs));
+ 	put_fs_long(current->screen_bitmap,&current->vm86_info->screen_bitmap);
+ 	tmp = current->tss.esp0;
+ 	current->tss.esp0 = current->saved_kernel_stack;
+ 	current->saved_kernel_stack = 0;
+ 	return (struct pt_regs *) tmp;
+ }
+ 
+ static void mark_screen_rdonly(struct task_struct * tsk)
+ {
+ 	unsigned long tmp;
+ 	unsigned long *pg_table;
+ 
+ 	if ((tmp = tsk->tss.cr3) != 0) {
+ 		tmp = *(unsigned long *) tmp;
+ 		if (tmp & PAGE_PRESENT) {
+ 			tmp &= PAGE_MASK;
+ 			pg_table = (0xA0000 >> PAGE_SHIFT) + (unsigned long *) tmp;
+ 			tmp = 32;
+ 			while (tmp--) {
+ 				if (PAGE_PRESENT & *pg_table)
+ 					*pg_table &= ~PAGE_RW;
+ 				pg_table++;
+ 			}
+ 		}
+ 	}
+ }
+ 
+ asmlinkage int sys_vm86(struct vm86_struct * v86)
+ {
+ 	struct vm86_struct info;
+ 	struct pt_regs * pt_regs = (struct pt_regs *) &v86;
+ 	int error;
+ 
+ 	if (current->saved_kernel_stack)
+ 		return -EPERM;
+ 	/* v86 must be readable (now) and writable (for save_v86_state) */
+ 	error = verify_area(VERIFY_WRITE,v86,sizeof(*v86));
+ 	if (error)
+ 		return error;
+ 	memcpy_fromfs(&info,v86,sizeof(info));
+ /*
+  * make sure the vm86() system call doesn't try to do anything silly
+  */
+ 	info.regs.__null_ds = 0;
+ 	info.regs.__null_es = 0;
+ 	info.regs.__null_fs = 0;
+ 	info.regs.__null_gs = 0;
+ /*
+  * The eflags register is also special: we cannot trust that the user
+  * has set it up safely, so this makes sure interrupt etc flags are
+  * inherited from protected mode.
+  */
+  	VEFLAGS = info.regs.eflags;
+ 	info.regs.eflags &= SAFE_MASK;
+ 	info.regs.eflags |= pt_regs->eflags & ~SAFE_MASK;
+ 	info.regs.eflags |= VM_MASK;
+ 
+ 	switch (info.cpu_type) {
+ 		case CPU_286:
+ 			current->v86mask = 0;
+ 			break;
+ 		case CPU_386:
+ 			current->v86mask = NT_MASK | IOPL_MASK;
+ 			break;
+ 		case CPU_486:
+ 			current->v86mask = AC_MASK | NT_MASK | IOPL_MASK;
+ 			break;
+ 		default:
+ 			current->v86mask = ID_MASK | AC_MASK | NT_MASK | IOPL_MASK;
+ 			break;
+ 	}
+ 
+ /*
+  * Save old state, set default return value (%eax) to 0
+  */
+ 	pt_regs->eax = 0;
+ 	current->saved_kernel_stack = current->tss.esp0;
+ 	current->tss.esp0 = (unsigned long) pt_regs;
+ 	current->vm86_info = v86;
+ 
+ 	current->screen_bitmap = info.screen_bitmap;
+ 	if (info.flags & VM86_SCREEN_BITMAP)
+ 		mark_screen_rdonly(current);
+ 	__asm__ __volatile__("movl %0,%%esp\n\t"
+ 		"jmp ret_from_sys_call"
+ 		: /* no outputs */
+ 		:"r" (&info.regs));
+ 	return 0;
+ }
+ 
+ static inline void return_to_32bit(struct vm86_regs * regs16, int retval)
+ {
+ 	struct pt_regs * regs32;
+ 
+ 	regs32 = save_v86_state(regs16);
+ 	regs32->eax = retval;
+ 	__asm__ __volatile__("movl %0,%%esp\n\t"
+ 		"jmp ret_from_sys_call"
+ 		: : "r" (regs32));
+ }
+ 
+ static inline void set_IF(struct vm86_regs * regs)
+ {
+ 	VEFLAGS |= VIF_MASK;
+ 	if (VEFLAGS & VIP_MASK)
+ 		return_to_32bit(regs, VM86_STI);
+ }
+ 
+ static inline void clear_IF(struct vm86_regs * regs)
+ {
+ 	VEFLAGS &= ~VIF_MASK;
+ }
+ 
+ static inline void clear_TF(struct vm86_regs * regs)
+ {
+ 	regs->eflags &= ~TF_MASK;
+ }
+ 
+ static inline void set_vflags_long(unsigned long eflags, struct vm86_regs * regs)
+ {
+ 	set_flags(VEFLAGS, eflags, current->v86mask);
+ 	set_flags(regs->eflags, eflags, SAFE_MASK);
+ 	if (eflags & IF_MASK)
+ 		set_IF(regs);
+ }
+ 
+ static inline void set_vflags_short(unsigned short flags, struct vm86_regs * regs)
+ {
+ 	set_flags(VFLAGS, flags, current->v86mask);
+ 	set_flags(regs->eflags, flags, SAFE_MASK);
+ 	if (flags & IF_MASK)
+ 		set_IF(regs);
+ }
+ 
+ static inline unsigned long get_vflags(struct vm86_regs * regs)
+ {
+ 	unsigned long flags = regs->eflags & RETURN_MASK;
+ 
+ 	if (VEFLAGS & VIF_MASK)
+ 		flags |= IF_MASK;
+ 	return flags | (VEFLAGS & current->v86mask);
+ }
+ 
+ static inline int is_revectored(int nr, struct revectored_struct * bitmap)
+ {
+ 	__asm__ __volatile__("btl %2,%%fs:%1\n\tsbbl %0,%0"
+ 		:"=r" (nr)
+ 		:"m" (*bitmap),"r" (nr));
+ 	return nr;
+ }
+ 
+ /*
+  * Boy are these ugly, but we need to do the correct 16-bit arithmetic.
+  * Gcc makes a mess of it, so we do it inline and use non-obvious calling
+  * conventions..
+  */
+ #define pushb(base, ptr, val) \
+ __asm__ __volatile__( \
+ 	"decw %w0\n\t" \
+ 	"movb %2,%%fs:0(%1,%0)" \
+ 	: "=r" (ptr) \
+ 	: "r" (base), "q" (val), "0" (ptr))
+ 
+ #define pushw(base, ptr, val) \
+ __asm__ __volatile__( \
+ 	"decw %w0\n\t" \
+ 	"movb %h2,%%fs:0(%1,%0)\n\t" \
+ 	"decw %w0\n\t" \
+ 	"movb %b2,%%fs:0(%1,%0)" \
+ 	: "=r" (ptr) \
+ 	: "r" (base), "q" (val), "0" (ptr))
+ 
+ #define pushl(base, ptr, val) \
+ __asm__ __volatile__( \
+ 	"decw %w0\n\t" \
+ 	"rorl $16,%2\n\t" \
+ 	"movb %h2,%%fs:0(%1,%0)\n\t" \
+ 	"decw %w0\n\t" \
+ 	"movb %b2,%%fs:0(%1,%0)\n\t" \
+ 	"decw %w0\n\t" \
+ 	"rorl $16,%2\n\t" \
+ 	"movb %h2,%%fs:0(%1,%0)\n\t" \
+ 	"decw %w0\n\t" \
+ 	"movb %b2,%%fs:0(%1,%0)" \
+ 	: "=r" (ptr) \
+ 	: "r" (base), "q" (val), "0" (ptr))
+ 
+ #define popb(base, ptr) \
+ ({ unsigned long __res; \
+ __asm__ __volatile__( \
+ 	"movb %%fs:0(%1,%0),%b2\n\t" \
+ 	"incw %w0" \
+ 	: "=r" (ptr), "=r" (base), "=r" (__res) \
+ 	: "0" (ptr), "1" (base), "2" (0)); \
+ __res; })
+ 
+ #define popw(base, ptr) \
+ ({ unsigned long __res; \
+ __asm__ __volatile__( \
+ 	"movb %%fs:0(%1,%0),%b2\n\t" \
+ 	"incw %w0\n\t" \
+ 	"movb %%fs:0(%1,%0),%h2\n\t" \
+ 	"incw %w0" \
+ 	: "=r" (ptr), "=r" (base), "=r" (__res) \
+ 	: "0" (ptr), "1" (base), "2" (0)); \
+ __res; })
+ 
+ #define popl(base, ptr) \
+ ({ unsigned long __res; \
+ __asm__ __volatile__( \
+ 	"movb %%fs:0(%1,%0),%b2\n\t" \
+ 	"incw %w0\n\t" \
+ 	"movb %%fs:0(%1,%0),%h2\n\t" \
+ 	"incw %w0\n\t" \
+ 	"rorl $16,%2\n\t" \
+ 	"movb %%fs:0(%1,%0),%b2\n\t" \
+ 	"incw %w0\n\t" \
+ 	"movb %%fs:0(%1,%0),%h2\n\t" \
+ 	"incw %w0\n\t" \
+ 	"rorl $16,%2" \
+ 	: "=r" (ptr), "=r" (base), "=r" (__res) \
+ 	: "0" (ptr), "1" (base)); \
+ __res; })
+ 
+ static void do_int(struct vm86_regs *regs, int i, unsigned char * ssp, unsigned long sp)
+ {
+ 	unsigned short seg = get_fs_word((void *) ((i<<2)+2));
+ 
+ 	if (seg == BIOSSEG || regs->cs == BIOSSEG ||
+ 	    is_revectored(i, &current->vm86_info->int_revectored))
+ 		return_to_32bit(regs, VM86_INTx + (i << 8));
+ 	if (i==0x21 && is_revectored((regs->eax >> 8) & 0xff,&current->vm86_info->int21_revectored)) {
+ 		return_to_32bit(regs, VM86_INTx + (i << 8));
+ 	}
+ 	pushw(ssp, sp, get_vflags(regs));
+ 	pushw(ssp, sp, regs->cs);
+ 	pushw(ssp, sp, IP(regs));
+ 	regs->cs = seg;
+ 	SP(regs) -= 6;
+ 	IP(regs) = get_fs_word((void *) (i<<2));
+ 	clear_TF(regs);
+ 	clear_IF(regs);
+ 	return;
+ }
+ 
+ 
+ void handle_vm86_fault(struct vm86_regs * regs, long error_code)
+ {
+ 	unsigned char *csp, *ssp;
+ 	unsigned long ip, sp;
+ 
+ 	csp = (unsigned char *) (regs->cs << 4);
+ 	ssp = (unsigned char *) (regs->ss << 4);
+ 	sp = SP(regs);
+ 	ip = IP(regs);
+ 
+ 	switch (popb(csp, ip)) {
+ 
+ 	/* operand size override */
+ 	case 0x66:
+ 		switch (popb(csp, ip)) {
+ 
+ 		/* pushfd */
+ 		case 0x9c:
+ 			SP(regs) -= 4;
+ 			IP(regs) += 2;
+ 			pushl(ssp, sp, get_vflags(regs));
+ 			return;
+ 
+ 		/* popfd */
+ 		case 0x9d:
+ 			SP(regs) += 4;
+ 			IP(regs) += 2;
+ 			set_vflags_long(popl(ssp, sp), regs);
+ 			return;
+ 		}
+ 
+ 	/* pushf */
+ 	case 0x9c:
+ 		SP(regs) -= 2;
+ 		IP(regs)++;
+ 		pushw(ssp, sp, get_vflags(regs));
+ 		return;
+ 
+ 	/* popf */
+ 	case 0x9d:
+ 		SP(regs) += 2;
+ 		IP(regs)++;
+ 		set_vflags_short(popw(ssp, sp), regs);
+ 		return;
+ 
+ 	/* int 3 */
+ 	case 0xcc:
+ 		IP(regs)++;
+ 		do_int(regs, 3, ssp, sp);
+ 		return;
+ 
+ 	/* int xx */
+ 	case 0xcd:
+ 		IP(regs) += 2;
+ 		do_int(regs, popb(csp, ip), ssp, sp);
+ 		return;
+ 
+ 	/* iret */
+ 	case 0xcf:
+ 		SP(regs) += 6;
+ 		IP(regs) = popw(ssp, sp);
+ 		regs->cs = popw(ssp, sp);
+ 		set_vflags_short(popw(ssp, sp), regs);
+ 		return;
+ 
+ 	/* cli */
+ 	case 0xfa:
+ 		IP(regs)++;
+ 		clear_IF(regs);
+ 		return;
+ 
+ 	/* sti */
+ 	case 0xfb:
+ 		IP(regs)++;
+ 		set_IF(regs);
+ 		return;
+ 
+ 	default:
+ 		return_to_32bit(regs, VM86_UNKNOWN);
+ 	}
+ }
