2 * Emulation of priviledged instructions
4 * Copyright 1995 Alexandre Julliard
12 #include "registers.h"
15 static int do_int(int intnum, struct sigcontext_struct *context)
19 case 0x10: return do_int10(context);
22 AX = DOS_GetEquipment();
27 return 1; /* get base mem size */
29 case 0x13: return do_int13(context);
30 case 0x15: return do_int15(context);
31 case 0x16: return do_int16(context);
32 case 0x1a: return do_int1a(context);
33 case 0x21: return do_int21(context);
42 case 0x25: return do_int25(context);
43 case 0x26: return do_int26(context);
44 case 0x2a: return do_int2a(context);
45 case 0x2f: return do_int2f(context);
46 case 0x31: return do_int31(context);
48 case 0x5c: return do_int5c(context);
51 fprintf(stderr,"int%02x: Unimplemented!\n", intnum);
58 /***********************************************************************
59 * INSTR_EmulateInstruction
61 * Emulate a priviledged instruction. Returns TRUE if emulation successful.
63 BOOL INSTR_EmulateInstruction( struct sigcontext_struct *context )
65 int prefix, segprefix, long_op, long_addr;
66 BYTE *instr = (BYTE *) PTR_SEG_OFF_TO_LIN( CS, IP );
68 /* First handle any possible prefix */
70 long_op = long_addr = (GET_SEL_FLAGS(CS) & LDT_FLAGS_32BIT) != 0;
71 segprefix = 0; /* no prefix */
78 segprefix = 1; /* CS */
81 segprefix = 2; /* SS */
84 segprefix = 3; /* DS */
87 segprefix = 4; /* ES */
90 segprefix = 5; /* FS */
93 segprefix = 6; /* GS */
96 long_op = !long_op; /* opcode size prefix */
99 long_addr = !long_addr; /* addr size prefix */
102 prefix = 0; /* no more prefixes */
112 /* Now look at the actual instruction */
116 case 0xcd: /* int <XX> */
118 if (!do_int(*instr, context))
120 fprintf(stderr,"Unexpected Windows interrupt %x\n", *instr);
123 EIP += 2; /* Bypass the int instruction */
126 case 0xcf: /* iret */
129 /* FIXME: should check the stack 'big' bit */
130 DWORD *stack = (WORD *)PTR_SEG_OFF_TO_LIN( SS, SP );
134 SP += 3*sizeof(DWORD); /* Pop the return address and flags */
138 /* FIXME: should check the stack 'big' bit */
139 WORD *stack = (WORD *)PTR_SEG_OFF_TO_LIN( SS, SP );
142 EFL = (EFL & 0xffff0000) | *stack;
143 SP += 3*sizeof(WORD); /* Pop the return address and flags */
147 case 0xe4: /* inb al,XX */
148 inportb_abs(context);
152 case 0xe5: /* in ax,XX */
153 inport_abs( context, long_op );
157 case 0xe6: /* outb XX,al */
158 outportb_abs(context);
162 case 0xe7: /* out XX,ax */
163 outport_abs( context, long_op );
167 case 0xec: /* inb al,dx */
172 case 0xed: /* in ax,dx */
173 inport( context, long_op );
177 case 0xee: /* outb dx,al */
182 case 0xef: /* out dx,ax */
183 outport( context, long_op );
187 case 0xfa: /* cli, ignored */
191 case 0xfb: /* sti, ignored */
196 fprintf(stderr, "Unexpected Windows program segfault"
197 " - opcode = %x\n", *instr);
198 return FALSE; /* Unable to emulate it */