OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [newlib/] [newlib/] [libc/] [sys/] [go32/] [dpmi.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 39 lampret
#include <stdlib.h>
2
#include "dos.h"
3
#include "go32.h"
4
#include <sys/types.h>
5
#include "dpmi.h"
6
 
7
static union REGS r;
8
static struct SREGS s;
9
 
10
int _go32_dpmi_allocate_dos_memory(_go32_dpmi_seginfo *info)
11
{
12
  r.x.ax = 0x0100;
13
  r.x.bx = info->size;
14
  int86(0x31, &r, &r);
15
  if (r.x.flags & 1)
16
  {
17
    info->size = r.x.bx;
18
    return r.x.ax;
19
  }
20
  else
21
  {
22
    info->rm_segment = r.x.ax;
23
    info->pm_selector = r.x.dx;
24
    return 0;
25
  }
26
}
27
 
28
int _go32_dpmi_free_dos_memory(_go32_dpmi_seginfo *info)
29
{
30
  r.x.ax = 0x0101;
31
  r.x.dx = info->pm_selector;
32
  int86(0x31, &r, &r);
33
  if (r.x.flags & 1)
34
  {
35
    return r.x.ax;
36
  }
37
  else
38
  {
39
    return 0;
40
  }
41
}
42
 
43
int _go32_dpmi_resize_dos_memory(_go32_dpmi_seginfo *info)
44
{
45
  r.x.ax = 0x0102;
46
  r.x.bx = info->size;
47
  r.x.dx = info->pm_selector;
48
  int86(0x31, &r, &r);
49
  if (r.x.flags & 1)
50
  {
51
    info->size = r.x.bx;
52
    return r.x.ax;
53
  }
54
  else
55
  {
56
    return 0;
57
  }
58
}
59
 
60
int _go32_dpmi_get_real_mode_interrupt_vector(int vector, _go32_dpmi_seginfo *info)
61
{
62
  r.x.ax = 0x0200;
63
  r.h.bl = vector;
64
  int86(0x31, &r, &r);
65
  info->rm_segment = r.x.cx;
66
  info->rm_offset = r.x.dx;
67
  return 0;
68
}
69
 
70
int _go32_dpmi_set_real_mode_interrupt_vector(int vector, _go32_dpmi_seginfo *info)
71
{
72
  r.x.ax = 0x0201;
73
  r.h.bl = vector;
74
  r.x.cx = info->rm_segment;
75
  r.x.dx = info->rm_offset;
76
  int86(0x31, &r, &r);
77
  return 0;
78
}
79
 
80
int _go32_dpmi_get_protected_mode_interrupt_vector(int vector, _go32_dpmi_seginfo *info)
81
{
82
  r.x.ax = 0x0204;
83
  r.h.bl = vector;
84
  int86(0x31, &r, &r);
85
  info->pm_selector = r.x.cx;
86
  info->pm_offset = r.x.dx;
87
  return 0;
88
}
89
 
90
int _go32_dpmi_set_protected_mode_interrupt_vector(int vector, _go32_dpmi_seginfo *info)
91
{
92
  r.x.ax = 0x0205;
93
  r.h.bl = vector;
94
  r.x.cx = info->pm_selector;
95
  r.x.dx = info->pm_offset;
96
  int86(0x31, &r, &r);
97
  if (r.x.flags & 1)
98
  {
99
    return r.x.ax;
100
  }
101
  else
102
  {
103
    return 0;
104
  }
105
}
106
 
107
/* In real DPMI, we enter with only CS known, and SS on a locked 4K stack which
108
   is *NOT* our SS.  We must set up everthing, including a stack swap, then
109
   restore it the way we found it.   C. Sandmann 4-93 */
110
 
111
static unsigned char wrapper_intcommon[] = {
112
0x1e,                                           /* push    ds                  */
113
0x06,                                           /* push    es                  */
114
0x0f, 0xa0,                                     /* push    fs                  */
115
0x0f, 0xa8,                                     /* push    gs                  */
116
0x60,                                           /* pusha                       */
117
0x66, 0xb8, 0x34, 0x12,                         /* mov     ax,0x1234           */
118
0x8e, 0xd8,                                     /* mov     ds,ax               */
119
0x8e, 0xc0,                                     /* mov     es,ax               */
120
0x8e, 0xe0,                                     /* mov     fs,ax               */
121
0x8e, 0xe8,                                     /* mov     gs,ax               */
122
0xbb, 0x00, 0x00, 0x00, 0x00,                   /* mov     ebx,_local_stack    */
123
0xfc,                                           /* cld                         */
124
0x89, 0xe1,                                     /* mov     ecx,esp             */
125
0x8c, 0xd2,                                     /* mov     dx,ss               */
126
0x8e, 0xd0,                                     /* mov     ss,ax               */
127
0x89, 0xdc,                                     /* mov     esp,ebx             */
128
0x52,                                           /* push    edx                 */
129
0x51,                                           /* push    ecx                 */
130
0xe8, 0x00, 0x00, 0x00, 0x00,                   /* call    _rmih               */
131
0x58,                                           /* pop     eax                 */
132
0x5b,                                           /* pop     ebx                 */
133
0x8e, 0xd3,                                     /* mov     ss,bx               */
134
0x89, 0xc4,                                     /* mov     esp,eax             */
135
0x61,                                           /* popa                        */
136
0x0f, 0xa9,                                     /* pop     gs                  */
137
0x0f, 0xa1,                                     /* pop     fs                  */
138
0x07,                                           /* pop     es                  */
139
0x1f                                            /* pop     ds                  */
140
};
141
 
142
static unsigned char wrapper_intiret[] = {
143
0xcf                                            /* iret                        */
144
};
145
 
146
static unsigned char wrapper_intchain[] = {
147
0x2e, 0xff, 0x2d, 0x00, 0x00, 0x00, 0x00,       /* jmp     cs:[_old_int+39]    */
148
0xcf,                                           /* iret                        */
149
0x78, 0x56, 0x34, 0x12,
150
0xcd, 0xab
151
};
152
 
153
/* _interrupt_stack_size can be changed globally before calling this routine if
154
   needed.  Don't change it between calls or you will mess up the malloc chain ! */
155
 
156
unsigned _interrupt_stack_size = 32256;
157
 
158
int _go32_dpmi_chain_protected_mode_interrupt_vector(int vector, _go32_dpmi_seginfo *info)
159
{
160
  char *mystack;
161
  unsigned char *wrapper = (unsigned char *)malloc(sizeof(wrapper_intcommon) + sizeof(wrapper_intchain));
162
  if (wrapper == 0)
163
    return 0x8015;
164
  mystack = (char *)malloc(_interrupt_stack_size);
165
  if (mystack == 0)
166
    return 0x8015;
167
 
168
  r.x.ax = 0x0204;
169
  r.h.bl = vector;
170
  int86(0x31, &r, &r);
171
 
172
  memcpy(wrapper, wrapper_intcommon, sizeof(wrapper_intcommon));
173
  memcpy(wrapper+sizeof(wrapper_intcommon), wrapper_intchain, sizeof(wrapper_intchain));
174
  *(short *)(wrapper+9) = _go32_my_ds();
175
  *(long *)(wrapper+20) = (int)mystack + _interrupt_stack_size;
176
  *(long *)(wrapper+36) = info->pm_offset - (int)wrapper - 40;
177
  *(long *)(wrapper+sizeof(wrapper_intcommon)+3) = (long)wrapper+sizeof(wrapper_intcommon)+8;
178
  *(long *)(wrapper+sizeof(wrapper_intcommon)+8) = r.x.dx;
179
  *(short *)(wrapper+sizeof(wrapper_intcommon)+12) = r.x.cx;
180
 
181
  r.x.ax = 0x0205;
182
  r.h.bl = vector;
183
  r.x.cx = _go32_my_cs();
184
  r.x.dx = (int)wrapper;
185
  int86(0x31, &r, &r);
186
  return 0;
187
}
188
 
189
int _go32_dpmi_allocate_iret_wrapper(_go32_dpmi_seginfo *info)
190
{
191
  char *mystack;
192
  unsigned char *wrapper = (unsigned char *)malloc(sizeof(wrapper_intcommon) + sizeof(wrapper_intiret));
193
  if (wrapper == 0)
194
    return 0x8015;
195
  mystack = (char *)malloc(_interrupt_stack_size);
196
  if (mystack == 0)
197
    return 0x8015;
198
 
199
  memcpy(wrapper, wrapper_intcommon, sizeof(wrapper_intcommon));
200
  memcpy(wrapper+sizeof(wrapper_intcommon), wrapper_intiret, sizeof(wrapper_intiret));
201
  *(short *)(wrapper+9) = _go32_my_ds();
202
  *(long *)(wrapper+20) = (int)mystack + _interrupt_stack_size;
203
  *(long *)(wrapper+36) = info->pm_offset - (int)wrapper - 40;
204
 
205
  info->pm_offset = (int)wrapper;
206
  return 0;
207
}
208
 
209
int _go32_dpmi_free_iret_wrapper(_go32_dpmi_seginfo *info)
210
{
211
  char *mystack;
212
  char *wrapper = (char *)info->pm_offset;
213
  mystack = (char *)(*(long *)(wrapper+20) - _interrupt_stack_size);
214
  free(mystack);
215
  free(wrapper);
216
  return 0;
217
}
218
 
219
int _go32_dpmi_simulate_int(int vector, _go32_dpmi_registers *regs)
220
{
221
  r.h.bl = vector;
222
  r.h.bh = 0;
223
  r.x.cx = 0;
224
  r.x.di = (int)regs;
225
  if (vector == 0x21 && regs->x.ax == 0x4b00)
226
  {
227
    r.x.ax = 0xff0a;
228
    int86(0x21, &r, &r);
229
  }
230
  else
231
  {
232
    r.x.ax = 0x0300;
233
    int86(0x31, &r, &r);
234
  }
235
  if (r.x.flags & 1)
236
  {
237
    return r.x.ax;
238
  }
239
  else
240
  {
241
    return 0;
242
  }
243
}
244
 
245
int _go32_dpmi_simulate_fcall(_go32_dpmi_registers *regs)
246
{
247
  r.x.ax = 0x0301;
248
  r.h.bh = 0;
249
  r.x.cx = 0;
250
  r.x.di = (int)regs;
251
  int86(0x31, &r, &r);
252
  if (r.x.flags & 1)
253
  {
254
    return r.x.ax;
255
  }
256
  else
257
  {
258
    return 0;
259
  }
260
}
261
 
262
int _go32_dpmi_simulate_fcall_iret(_go32_dpmi_registers *regs)
263
{
264
  r.x.ax = 0x0302;
265
  r.h.bh = 0;
266
  r.x.cx = 0;
267
  r.x.di = (int)regs;
268
  int86(0x31, &r, &r);
269
  if (r.x.flags & 1)
270
  {
271
    return r.x.ax;
272
  }
273
  else
274
  {
275
    return 0;
276
  }
277
}
278
 
279
/* Bug here; this needs to be fixed like above with SS & CLD */
280
 
281
static unsigned char wrapper_common[] = {
282
0x66, 0x06,                             /* push    es                  */
283
0x66, 0x1e,                             /* push    ds                  */
284
0x66, 0x06,                             /* push    es                  */
285
0x66, 0x1f,                             /* pop     ds                  */
286
0x56,                                   /* push    esi                 */
287
0x57,                                   /* push    edi                 */
288
0xe8, 0x00, 0x00, 0x00, 0x00,           /* call    _rmcb               */
289
0x5f,                                   /* pop     edi                 */
290
0x5e,                                   /* pop     esi                 */
291
0x66, 0x1f,                             /* pop     ds                  */
292
0x66, 0x07,                             /* pop     es                  */
293
0xfc,                                   /* cld                         */
294
0x66, 0x8b, 0x06,                       /* mov     ax,[esi]            */
295
0x66, 0x26, 0x89, 0x47, 0x2a,           /* mov     es:[edi+42],ax      */
296
0x66, 0x8b, 0x46, 0x02,                 /* mov     ax,[esi+2]          */
297
0x66, 0x26, 0x89, 0x47, 0x2c,           /* mov     es:[edi+44],ax      */
298
};
299
 
300
static unsigned char wrapper_retf[] = {
301
0x66, 0x26, 0x83, 0x47, 0x2e, 0x04,     /* add     es:[edi+46],0x4     */
302
0xcf                                    /* iret                        */
303
};
304
 
305
static unsigned char wrapper_iret[] = {
306
0x66, 0x8b, 0x46, 0x04,                 /* mov     ax,[esi+4]          */
307
0x66, 0x26, 0x89, 0x47, 0x20,           /* mov     es:[edi+32],ax      */
308
0x66, 0x26, 0x83, 0x47, 0x2e, 0x06,     /* add     es:[edi+46],0x6     */
309
0xcf                                    /* iret                        */
310
};
311
 
312
int _go32_dpmi_allocate_real_mode_callback_retf(_go32_dpmi_seginfo *info, _go32_dpmi_registers *regs)
313
{
314
  unsigned char *wrapper = (unsigned char *)malloc(sizeof(wrapper_common) + sizeof(wrapper_retf));
315
  if (wrapper == 0)
316
    return 0x8015;
317
 
318
  memcpy(wrapper, wrapper_common, sizeof(wrapper_common));
319
  memcpy(wrapper+sizeof(wrapper_common), wrapper_retf, sizeof(wrapper_retf));
320
  *(long *)(wrapper+11) = info->pm_offset - (int)wrapper - 15;
321
  info->size = (int)wrapper;
322
 
323
  r.x.ax = 0x0303;
324
  r.x.si = (int)wrapper;
325
  r.x.di = (int)regs;
326
  s.ds = _go32_my_cs();
327
  s.es = _go32_my_ds();
328
  s.fs = 0;
329
  s.gs = 0;
330
  int86x(0x31, &r, &r, &s);
331
  if (r.x.flags & 1)
332
  {
333
    return r.x.ax;
334
  }
335
  else
336
  {
337
    info->rm_segment = r.x.cx;
338
    info->rm_offset = r.x.dx;
339
    return 0;
340
  }
341
}
342
 
343
int _go32_dpmi_allocate_real_mode_callback_iret(_go32_dpmi_seginfo *info, _go32_dpmi_registers *regs)
344
{
345
  unsigned char *wrapper = (unsigned char *)malloc(sizeof(wrapper_common) + sizeof(wrapper_iret));
346
  if (wrapper == 0)
347
    return 0x8015;
348
 
349
  memcpy(wrapper, wrapper_common, sizeof(wrapper_common));
350
  memcpy(wrapper+sizeof(wrapper_common), wrapper_iret, sizeof(wrapper_iret));
351
  *(long *)(wrapper+11) = info->pm_offset - (int)wrapper - 15;
352
  info->size = (int)wrapper;
353
 
354
  r.x.ax = 0x0303;
355
  r.x.si = (int)wrapper;
356
  r.x.di = (int)regs;
357
  s.ds = _go32_my_cs();
358
  s.es = _go32_my_ds();
359
  s.fs = 0;
360
  s.gs = 0;
361
  int86x(0x31, &r, &r, &s);
362
  if (r.x.flags & 1)
363
  {
364
    return r.x.ax;
365
  }
366
  else
367
  {
368
    info->rm_segment = r.x.cx;
369
    info->rm_offset = r.x.dx;
370
    return 0;
371
  }
372
}
373
 
374
int _go32_dpmi_free_real_mode_callback(_go32_dpmi_seginfo *info)
375
{
376
  free((char *)info->size);
377
  r.x.ax = 0x0304;
378
  r.x.cx = info->rm_segment;
379
  r.x.dx = info->rm_offset;
380
  int86(0x31, &r, &r);
381
  if (r.x.flags & 1)
382
  {
383
    return r.x.ax;
384
  }
385
  else
386
  {
387
    return 0;
388
  }
389
}
390
 
391
int _go32_dpmi_get_free_memory_information(_go32_dpmi_meminfo *info)
392
{
393
  r.x.ax = 0x0500;
394
  r.x.di = (int)info;
395
  int86(0x31, &r, &r);
396
  return 0;
397
}
398
 
399
u_long _go32_dpmi_remaining_physical_memory()
400
{
401
  _go32_dpmi_meminfo info;
402
  _go32_dpmi_get_free_memory_information(&info);
403
  if (info.available_physical_pages)
404
    return info.available_physical_pages * 4096;
405
  return info.available_memory;
406
}
407
 
408
u_long _go32_dpmi_remaining_virtual_memory()
409
{
410
  _go32_dpmi_meminfo info;
411
  _go32_dpmi_get_free_memory_information(&info);
412
  return info.available_memory;
413
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.