4 * Copyright 1995 Alexandre Julliard
12 #include "registers.h"
16 /* #define DEBUG_INT */
20 /* Structure for real-mode callbacks */
42 /**********************************************************************
45 * Handler for int 31h (DPMI).
47 void INT_Int31Handler( struct sigcontext_struct context
)
52 RESET_CFLAG(&context
);
53 switch(AX_reg(&context
))
55 case 0x0000: /* Allocate LDT descriptors */
56 if (!(AX_reg(&context
) = AllocSelectorArray( CX_reg(&context
) )))
58 AX_reg(&context
) = 0x8011; /* descriptor unavailable */
63 case 0x0001: /* Free LDT descriptor */
64 if (FreeSelector( BX_reg(&context
) ))
66 AX_reg(&context
) = 0x8022; /* invalid selector */
71 case 0x0003: /* Get next selector increment */
72 AX_reg(&context
) = __AHINCR
;
75 case 0x0004: /* Lock selector (not supported) */
76 AX_reg(&context
) = 0; /* FIXME: is this a correct return value? */
79 case 0x0005: /* Unlock selector (not supported) */
80 AX_reg(&context
) = 0; /* FIXME: is this a correct return value? */
83 case 0x0006: /* Get selector base address */
84 if (!(dw
= GetSelectorBase( BX_reg(&context
) )))
86 AX_reg(&context
) = 0x8022; /* invalid selector */
91 CX_reg(&context
) = HIWORD(dw
);
92 DX_reg(&context
) = LOWORD(dw
);
96 case 0x0007: /* Set selector base address */
97 SetSelectorBase( BX_reg(&context
),
98 MAKELONG( DX_reg(&context
), CX_reg(&context
) ) );
101 case 0x0008: /* Set selector limit */
102 SetSelectorLimit( BX_reg(&context
),
103 MAKELONG( DX_reg(&context
), CX_reg(&context
) ) );
106 case 0x0009: /* Set selector access rights */
107 SelectorAccessRights( BX_reg(&context
), 1, CX_reg(&context
) );
109 case 0x000a: /* Allocate selector alias */
110 if (!(AX_reg(&context
) = AllocCStoDSAlias( BX_reg(&context
) )))
112 AX_reg(&context
) = 0x8011; /* descriptor unavailable */
117 case 0x000b: /* Get descriptor */
120 LDT_GetEntry( SELECTOR_TO_ENTRY( BX_reg(&context
) ), &entry
);
121 /* FIXME: should use ES:EDI for 32-bit clients */
122 LDT_EntryToBytes( PTR_SEG_OFF_TO_LIN( ES_reg(&context
),
123 DI_reg(&context
) ), &entry
);
127 case 0x000c: /* Set descriptor */
130 LDT_BytesToEntry( PTR_SEG_OFF_TO_LIN( ES_reg(&context
),
131 DI_reg(&context
) ), &entry
);
132 LDT_GetEntry( SELECTOR_TO_ENTRY( BX_reg(&context
) ), &entry
);
136 case 0x000d: /* Allocate specific LDT descriptor */
137 AX_reg(&context
) = 0x8011; /* descriptor unavailable */
141 case 0x0204: /* Get protected mode interrupt vector */
142 dw
= (DWORD
)INT_GetHandler( BL_reg(&context
) );
143 CX_reg(&context
) = HIWORD(dw
);
144 DX_reg(&context
) = LOWORD(dw
);
147 case 0x0205: /* Set protected mode interrupt vector */
148 INT_SetHandler( BL_reg(&context
),
149 (SEGPTR
)MAKELONG( DX_reg(&context
), CX_reg(&context
) ));
152 case 0x0300: /* Simulate real mode interrupt
153 * Interrupt number is in BL, flags are in BH
154 * ES:DI points to real-mode call structure
155 * Currently we just print it out and return error.
158 REALMODECALL
*p
= (REALMODECALL
*)PTR_SEG_OFF_TO_LIN( ES_reg(&context
), DI_reg(&context
) );
160 "RealModeInt %02x: EAX=%08lx EBX=%08lx ECX=%08lx EDX=%08lx\n"
161 " ESI=%08lx EDI=%08lx ES=%04x DS=%04x\n",
162 BL_reg(&context
), p
->eax
, p
->ebx
, p
->ecx
, p
->edx
,
163 p
->esi
, p
->edi
, p
->es
, p
->ds
);
168 case 0x0301: /* Call real mode procedure with far return */
170 REALMODECALL
*p
= (REALMODECALL
*)PTR_SEG_OFF_TO_LIN( ES_reg(&context
), DI_reg(&context
) );
172 "RealModeCall: EAX=%08lx EBX=%08lx ECX=%08lx EDX=%08lx\n"
173 " ESI=%08lx EDI=%08lx ES=%04x DS=%04x CS:IP=%04x:%04x\n",
174 p
->eax
, p
->ebx
, p
->ecx
, p
->edx
,
175 p
->esi
, p
->edi
, p
->es
, p
->ds
, p
->cs
, p
->ip
);
180 case 0x0302: /* Call real mode procedure with interrupt return */
182 REALMODECALL
*p
= (REALMODECALL
*)PTR_SEG_OFF_TO_LIN( ES_reg(&context
), DI_reg(&context
) );
184 "RealModeCallIret: EAX=%08lx EBX=%08lx ECX=%08lx EDX=%08lx\n"
185 " ESI=%08lx EDI=%08lx ES=%04x DS=%04x CS:IP=%04x:%04x\n",
186 p
->eax
, p
->ebx
, p
->ecx
, p
->edx
,
187 p
->esi
, p
->edi
, p
->es
, p
->ds
, p
->cs
, p
->ip
);
192 case 0x0400: /* Get DPMI version */
193 AX_reg(&context
) = 0x005a; /* DPMI version 0.90 */
194 BX_reg(&context
) = 0x0005; /* Flags: 32-bit, virtual memory */
195 CL_reg(&context
) = runtime_cpu ();
196 DX_reg(&context
) = 0x0102; /* Master/slave interrupt controller base*/
199 case 0x0500: /* Get free memory information */
200 ptr
= (BYTE
*)PTR_SEG_OFF_TO_LIN( ES_reg(&context
), DI_reg(&context
) );
201 *(DWORD
*)ptr
= 0x00ff0000; /* Largest block available */
202 memset( ptr
+ 4, 0xff, 0x2c ); /* No other information supported */
205 case 0x0501: /* Allocate memory block */
206 if (!(ptr
= (BYTE
*)malloc( MAKELONG( CX_reg(&context
),
207 BX_reg(&context
) ) )))
209 AX_reg(&context
) = 0x8012; /* linear memory not available */
214 BX_reg(&context
) = SI_reg(&context
) = HIWORD(ptr
);
215 CX_reg(&context
) = DI_reg(&context
) = LOWORD(ptr
);
219 case 0x0502: /* Free memory block */
220 free( (void *)MAKELONG( DI_reg(&context
), SI_reg(&context
) ) );
223 case 0x0503: /* Resize memory block */
224 if (!(ptr
= (BYTE
*)realloc( (void *)MAKELONG(DI_reg(&context
),SI_reg(&context
)),
225 MAKELONG(CX_reg(&context
),BX_reg(&context
)))))
227 AX_reg(&context
) = 0x8012; /* linear memory not available */
232 BX_reg(&context
) = SI_reg(&context
) = HIWORD(ptr
);
233 CX_reg(&context
) = DI_reg(&context
) = LOWORD(ptr
);
237 case 0x0600: /* Lock linear region */
238 break; /* Just ignore it */
240 case 0x0601: /* Unlock linear region */
241 break; /* Just ignore it */
244 INT_BARF( &context
, 0x31 );
245 AX_reg(&context
) = 0x8001; /* unsupported function */