home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / dos / grafik / pmod01 / source / pmode.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-03-10  |  20.1 KB  |  880 lines

  1. /****************************************************************************
  2. *
  3. *                          Protected Mode Library
  4. *
  5. *                    Copyright (C) 1994 SciTech Software.
  6. *                            All rights reserved.
  7. *
  8. * Filename:        $RCSfile: pmode.c $
  9. * Version:        $Revision: 1.1 $
  10. *
  11. * Language:        ANSI C
  12. * Environment:    IBM PC (MSDOS) Real mode and 16/32 bit Protected Mode
  13. *
  14. * Description:    Module implementing DOS extender independant protected
  15. *                mode programming. This module will need to be included in
  16. *                all programs that use SciTech Software's products that
  17. *                are to be compiled in protected mode, and will need to be
  18. *                compile with the correct defines for the DOS extender that
  19. *                you will be using (or with no defines for real mode
  20. *                emulation of these routines).
  21. *
  22. * $Id: pmode.c 1.1 1994/03/10 09:05:43 kjb release $
  23. *
  24. ****************************************************************************/
  25.  
  26. #include <stdlib.h>
  27. #include "pmode.h"
  28.  
  29. /*----------------------------- Implementation ----------------------------*/
  30.  
  31. /* Set the type target being compiled for so that we can do switching at
  32.  * runtime as well as compile time.
  33.  */
  34.  
  35. #if    defined(REALMODE)
  36. int    _PMODE_modeType = PMODE_realMode;
  37. #elif defined(PMODE286)
  38. int _PMODE_modeType = PMODE_286;
  39. #elif defined(PMODE386)
  40. int _PMODE_modeType = PMODE_386;
  41. #endif
  42.  
  43. static void *bios = NULL;
  44.  
  45. void * PMODE_getBIOSPointer(void)
  46. {
  47.     if (bios == NULL)
  48.         bios = PMODE_mapLinearPointer(MK_PHYS(0x40, 0x00), 0xFFFF);
  49.     return bios;
  50. }
  51.  
  52. /*-------------------------------------------------------------------------*/
  53. /* DOS Real Mode support.                                                   */
  54. /*-------------------------------------------------------------------------*/
  55.  
  56. #ifdef REALMODE
  57.  
  58. void * PMODE_mapLinearPointer(long base, unsigned limit)
  59. {
  60.     /* Simply create a far pointer to the base address and ignore limit */
  61.     int seg = base >> 4;
  62.     int offset = base - (seg << 4);
  63.     limit = limit;
  64.     return MK_FP(seg, offset);
  65. }
  66.  
  67. void PMODE_freeLinearPointer(void *ptr)
  68. {
  69.     /* No need to do anything here */
  70.     ptr = ptr;
  71. }
  72.  
  73. void * PMODE_allocRealSeg(unsigned short size, unsigned long *segid,
  74.     unsigned *segment, unsigned *offset)
  75. {
  76.     /* Call malloc() to allocate the memory for us */
  77.     void *p = malloc(size);
  78.     *segid = (unsigned long)p;
  79.     *segment = FP_SEG(p);
  80.     *offset = FP_OFF(p);
  81.     return p;
  82. }
  83.  
  84. void PMODE_freeRealSeg(unsigned long segid)
  85. {
  86.     free((void *)segid);
  87. }
  88.  
  89. void * PMODE_createCSAlias(void *dataptr)
  90. {
  91.     return dataptr;
  92. }
  93.  
  94. void PMODE_freeCSAlias(void * alias)
  95. {
  96.     alias = alias;
  97. }
  98.  
  99. void far * PMODE_createDSAlias(void (*codeptr)())
  100. {
  101.     return (void far *)codeptr;
  102. }
  103.  
  104. void PMODE_freeDSAlias(void far * alias)
  105. {
  106.     alias = alias;
  107. }
  108.  
  109. int PMODE_int86(int intno, RMREGS *in, RMREGS *out)
  110. {
  111.     return int86(intno,in,out);
  112. }
  113.  
  114. int PMODE_int86x(int intno, RMREGS *in, RMREGS *out,
  115.     RMSREGS *sregs)
  116. {
  117.     return int86x(intno,in,out,sregs);
  118. }
  119.  
  120. int PMODE_installMouseHandler(int mask, void (cdecl far * handler)())
  121. {
  122.     union REGS        regs;
  123.     struct SREGS    sregs;
  124.  
  125.     sregs.es = FP_SEG(handler);
  126.     regs.x.dx = FP_OFF(handler);
  127.     regs.x.cx = mask;
  128.     regs.x.ax = 20;
  129.     int86x(0x33, ®s, ®s, &sregs);
  130.     return 1;
  131. }
  132.  
  133. void far * PMODE_getISR(int intno, SAVEINT *save)
  134. {
  135.     save->real_isr = (unsigned long)_dos_getvect(intno);
  136.     return (void far *)save->real_isr;
  137. }
  138.  
  139. typedef void (interrupt far *intfp)();
  140.  
  141. void PMODE_restoreISR(int intno, SAVEINT *save)
  142. {
  143.     _dos_setvect(intno, (intfp)save->real_isr);
  144. }
  145.  
  146. void PMODE_setISR(int intno, void far *isr)
  147. {
  148.     _dos_setvect(intno, (intfp)isr);
  149. }
  150.  
  151. #endif
  152.  
  153. /*-------------------------------------------------------------------------*/
  154. /* Generic DPMI support.                                                   */
  155. /* UNTESTED                                                                   */
  156. /*-------------------------------------------------------------------------*/
  157.  
  158. #ifdef DPMI
  159.  
  160. void * PMODE_mapLinearPointer(long base, unsigned limit)
  161. {
  162.     int            sel;
  163.     union REGS    r;
  164.  
  165.     /* Under DPMI the pointer that we allocate will have a maximum
  166.      * limit of 64k
  167.      */
  168.  
  169.     /* Allocate 1 descriptor */
  170.     r.x.ax = 0;
  171.     r.x.cx = 1;
  172.     int86(0x31, &r, &r);
  173.     if (r.x.cflag) return NULL;
  174.  
  175.     /* Set base address */
  176.     sel = r.x.bx = r.x.ax;
  177.     r.x.ax = 7;
  178.     r.x.cx = base >> 16;
  179.     r.x.dx = base & 0xFFFF;
  180.     int86(0x31, &r, &r);
  181.     if (r.x.cflag) return NULL;
  182.  
  183.     /* Set limit */
  184.     r.x.ax = 8;
  185.     r.x.cx = 0;
  186.     r.x.dx = limit;
  187.     int86(0x31, &r, &r);
  188.     if (r.x.cflag) return NULL;
  189.  
  190.     return MK_FP(sel, 0);
  191. }
  192.  
  193. void PMODE_freeLinearPointer(void *ptr)
  194. {
  195.     union REGS    r;
  196.  
  197.     r.x.ax = 1;
  198.     r.x.bx = FP_SEG(ptr);
  199.     int86(0x31, &r, &r);
  200. }
  201.  
  202. /* This needs to be filled in with the remaining functions */
  203.  
  204. #endif
  205.  
  206. /*-------------------------------------------------------------------------*/
  207. /* Phar Lap 286|DOS Extender support.                                       */
  208. /* No Interrupt support at this stage                                      */
  209. /*-------------------------------------------------------------------------*/
  210.  
  211. #ifdef PHARLAP286
  212.  
  213. #include <phapi.h>
  214.  
  215. void * PMODE_mapLinearPointer(long base, unsigned limit)
  216. {
  217.     int seg,off;
  218.     SEL    sel;
  219.  
  220.     /* Compute segment and offset of address */
  221.     seg = base >> 4;
  222.     off = base - (seg << 4);
  223.  
  224.     /* Make segment */
  225.     if (DosMapRealSeg(seg, (ULONG)limit+off+1, &sel)) return NULL;
  226.     return MK_FP(sel, off);
  227. }
  228.  
  229. void PMODE_freeLinearPointer(void *ptr)
  230. {
  231.     DosFreeSeg(FP_SEG(ptr));
  232. }
  233.  
  234. void * PMODE_allocRealSeg(unsigned short size, unsigned long *segid,
  235.     unsigned *segment, unsigned *offset)
  236. {
  237.     SEL    sel;
  238.  
  239.     if (DosAllocRealSeg(size, (PUSHORT)segment, segid))
  240.         return NULL;
  241.     *offset = 0;
  242.     return MK_FP(*segid, 0);
  243. }
  244.  
  245. void PMODE_freeRealSeg(unsigned long segid)
  246. {
  247.     DosFreeSeg(segid);
  248. }
  249.  
  250. /* The following CS alias routines do not seem to work with blocks of
  251.  * memory that have been allocate with malloc(), but only with memory in
  252.  * in the DGROUP data segment. Maybe there is an alternative method
  253.  * of doing this with Phar Lap that will solve this problem?
  254.  */
  255.  
  256. void * PMODE_createCSAlias(void *dataptr)
  257. {
  258.     SEL sel;
  259.  
  260.     if (DosCreateCSAlias(FP_SEG(dataptr), &sel))
  261.         return NULL;
  262.     return MK_FP(sel, FP_OFF(dataptr));
  263. }
  264.  
  265. void PMODE_freeCSAlias(void *alias)
  266. {
  267.     DosFreeSeg(FP_SEG(alias));
  268. }
  269.  
  270. void far * PMODE_createDSAlias(void (*codeptr)())
  271. {
  272.     SEL sel;
  273.  
  274.     if (DosCreateDSAlias(FP_SEG(codeptr), &sel))
  275.         return NULL;
  276.     return MK_FP(sel, FP_OFF(codeptr));
  277. }
  278.  
  279. void PMODE_freeDSAlias(void far *alias)
  280. {
  281.     DosFreeSeg(FP_SEG(alias));
  282. }
  283.  
  284. #define    IN(reg)        r.reg = in->x.reg
  285. #define    OUT(reg)    out->x.reg = r.reg
  286.  
  287. int PMODE_int86(int intno, RMREGS *in, RMREGS *out)
  288. {
  289.     REGS16    r;
  290.  
  291.     r.flags = 0;
  292.     IN(ax); IN(bx); IN(cx); IN(dx); IN(si); IN(di);
  293.     DosRealIntr(intno, &r, 0, 0);
  294.     OUT(ax); OUT(bx); OUT(cx); OUT(dx); OUT(si); OUT(di);
  295.     return r.ax;
  296. }
  297.  
  298. int PMODE_int86x(int intno, RMREGS *in, RMREGS *out, RMSREGS *sregs)
  299. {
  300.     REGS16    r;
  301.  
  302.     r.cs = sregs->cs; r.ds = sregs->ds; r.es = sregs->es;
  303.     r.flags = 0;
  304.     IN(ax); IN(bx); IN(cx); IN(dx); IN(si); IN(di);
  305.     DosRealIntr(intno, &r, 0, 0);
  306.     sregs->cs = r.cs; sregs->ds = r.ds; sregs->es = r.es;
  307.     OUT(ax); OUT(bx); OUT(cx); OUT(dx); OUT(si); OUT(di);
  308.     return r.ax;
  309. }
  310.  
  311. #endif
  312.  
  313. /*-------------------------------------------------------------------------*/
  314. /* Ergo DPM support.                                                       */
  315. /* UNTESTED                                                                   */
  316. /*-------------------------------------------------------------------------*/
  317.  
  318. #ifdef ERGODPM
  319.  
  320. void * PMODE_mapLinearPointer(long base, unsigned limit)
  321. {
  322.     int    sel,seg,off;
  323.  
  324.     /* Compute segment */
  325.     seg = base >> 4;
  326.     off = base - (seg << 4);
  327.     limit = limit;
  328.  
  329.     /* Make segment */
  330.     ParaToSel(seg, &sel);
  331.  
  332.     /* Construct pointer */
  333.     return MK_FP(sel, off);
  334. }
  335.  
  336. void PMODE_freeLinearPointer(void *ptr)
  337. {
  338.     /* Freeing selector from ParaToSel is unwise since they are a global
  339.      * resource
  340.      */
  341.     ptr = ptr;
  342. }
  343.  
  344. /* This needs to be filled in with the remaining functions */
  345.  
  346. #endif
  347.  
  348. /*-------------------------------------------------------------------------*/
  349. /* Phar Lap 386|DOS Extender support.                                       */
  350. /* UNTESTED                                                                   */
  351. /*-------------------------------------------------------------------------*/
  352.  
  353. #ifdef PHARLAP386
  354.  
  355. void * PMODE_mapLinearPointer(long base, unsigned limit)
  356. {
  357. #if 0
  358.     union REGS         r;
  359.     struct SREGS     s;
  360.  
  361.     /* Init segment registers */
  362.     segread(&s);
  363.  
  364.     /* allocate 0 length segment */
  365.     r.h.ah = 0x48;
  366.     r.x.ebx = 0;
  367.     int86(0x21, &r, &r);
  368.     if (r.x.cflag) return NULL;
  369.  
  370.     /* Modify base/length of segment */
  371.     s.es = r.x.ax;
  372.     r.x.ax = 0x250A;
  373.     r.x.ebx = base;                        /* Base address */
  374.     r.x.ecx = ((limit+1)+4095)/4096;    /* Map 4K pages */
  375.     int86x(0x21, &r, &r, &s);
  376.     if (r.x.cflag) return NULL;
  377.  
  378.     return MK_FP(s.es, r.x.eax);
  379. #endif
  380.     /* This needs to be re-written to return a near pointer */
  381.     return NULL;
  382. }
  383.  
  384. void PMODE_freeLinearPointer(void *ptr)
  385. {
  386. #if 0
  387.     union REGS         r;
  388.     struct SREGS     s;
  389.  
  390.     segread(&s);
  391.     s.es = FP_SEG(ptr);
  392.     r.h.ah = 0x49;
  393.     int86x(0x21, &r, &r, &s);
  394. #endif
  395. }
  396.  
  397. /* This needs to be filled in with the remaining functions */
  398.  
  399. #endif
  400.  
  401. /*-------------------------------------------------------------------------*/
  402. /* Symantec C++ DOSX support (also X32-VM support).                           */
  403. /*-------------------------------------------------------------------------*/
  404.  
  405. #ifdef    DOSX
  406.  
  407. /* Maintain a near pointer to the low 1Mb memory area */
  408.  
  409. static char *lowmemory = NULL;
  410.  
  411. void * PMODE_mapLinearPointer(long base, unsigned limit)
  412. {
  413.     if (lowmemory == NULL)
  414.         lowmemory = _x386_map_physical_address(0, 1024L*1024L);
  415.     return (void*)(lowmemory + base);
  416. }
  417.  
  418. void PMODE_freeLinearPointer(void *ptr)
  419. {
  420.     /* No need to do anything here */
  421.     ptr = ptr;
  422. }
  423.  
  424. void * PMODE_allocRealSeg(unsigned short size, unsigned long *segid,
  425.     unsigned *segment, unsigned *offset)
  426. {
  427.     union REGS    r;
  428.  
  429.     r.h.ah = 0x48;                    /* DOS function 48h - allocate mem    */
  430.     r.x.bx = (size + 0xF) >> 4;        /* Number of paragraphs to allocate    */
  431.     int86(0x21, &r, &r);            /* Call DOS extender                */
  432.     if (r.x.cflag)
  433.         return NULL;                /* Could not allocate the memory    */
  434.     *segment = r.x.ax;
  435.     *offset = 0;
  436.     *segid = -1;
  437.     return (void*)r.e.ebx;
  438. }
  439.  
  440. void PMODE_freeRealSeg(unsigned long segid)
  441. {
  442.     /* Cannot de-allocate this memory */
  443.     segid = segid;
  444. }
  445.  
  446. void * PMODE_createCSAlias(void *dataptr)
  447. {
  448.     return dataptr;
  449. }
  450.  
  451. void PMODE_freeCSAlias(void * alias)
  452. {
  453.     alias = alias;
  454. }
  455.  
  456. void far * PMODE_createDSAlias(void (*codeptr)())
  457. {
  458.     union REGS    r;
  459.     unsigned    sel;
  460.  
  461.     r.x.ax = 0x3501;            /* Allocate protected mode selector        */
  462.     int86(0x21, &r, &r);
  463.     if (r.x.cflag) return NULL;    /* No selectors left! */
  464.     sel = r.x.bx;
  465.  
  466.     r.x.ax = 0x3504;            /* Get Selector base address            */
  467.     r.x.bx = FP_SEG(codeptr);    /* of current code segment                */
  468.     int86(0x21, &r, &r);
  469.     if (r.x.cflag) return NULL;
  470.  
  471.     r.x.ax = 0x3503;            /* Set Selector base address            */
  472.     r.x.bx = sel;
  473.     int86(0x21, &r, &r);
  474.     if (r.x.cflag) return NULL;
  475.  
  476.     r.x.ax = 0x3505;            /* Set Selector limit                    */
  477.     r.x.bx = sel;
  478.     r.e.ecx = 0xFFFFFFFF;
  479.     int86(0x21, &r, &r);
  480.     if (r.x.cflag) return NULL;
  481.  
  482.     return MK_FP(sel, FP_OFF(codeptr));
  483. }
  484.  
  485. void PMODE_freeDSAlias(void far *alias)
  486. {
  487.     union REGS    r;
  488.  
  489.     r.x.ax = 0x3502;            /* De-allocate protected mode selector    */
  490.     r.x.bx = FP_SEG(alias);
  491.     int86(0x21, &r, &r);
  492. }
  493.  
  494. int PMODE_int86(int intno, RMREGS *in, RMREGS *out)
  495. {
  496.     return int86_real(intno,in,out);
  497. }
  498.  
  499. int PMODE_int86x(int intno, RMREGS *in, RMREGS *out, RMSREGS *sregs)
  500. {
  501.     return int86x_real(intno,in,out,sregs);
  502. }
  503.  
  504. #include <msmouse.h>
  505.  
  506. static void (cdecl far *_handler)() = NULL;
  507. static char _ms_stack[1024];
  508.  
  509. void _ms_handler(unsigned mask, unsigned state, unsigned curposx,
  510.     unsigned curposy)
  511. {
  512. asm {    mov eax,mask;        /* Load params back into registers    */
  513.         mov    ebx,state;
  514.         mov    ecx,curposx;
  515.         mov edx,curposy; }
  516.     _handler();             /* Call event handling routine      */
  517. }
  518.  
  519. int PMODE_installMouseHandler(int mask, void (cdecl far * handler)())
  520. {
  521.     /* For some reason Symantec C++ does not seem to correctly set the
  522.      * segment values for external assemly routines assembled with TASM.
  523.      * Hence since we know the routine is in the same code segment, we
  524.      * force the code segment value here.
  525.      */
  526.     _handler = MK_FP(FP_SEG(_ms_handler), (long)handler);
  527.     msm_signal(0xFFFF, _ms_handler, &_ms_stack[1024]);
  528.     return 1;
  529. }
  530.  
  531. void far * PMODE_getISR(int intno, SAVEINT *save)
  532. {
  533.     union REGS      r;
  534.     struct SREGS    s;
  535.  
  536.     segread(&s);
  537.     r.x.ax = 0x2502;        /* Get pmode interrupt vector        */
  538.     r.x.cx = intno;
  539.     int86x(0x21, &r, &r, &s);
  540.     save->pmode_isr = MK_FP(s.es, r.e.ebx);
  541.  
  542.     r.x.ax = 0x2503;        /* Get real mode interrupt vector    */
  543.     r.x.cx = intno;
  544.     int86(0x21, &r, &r);
  545.     save->real_isr = r.e.ebx;
  546.  
  547.     return save->pmode_isr;
  548. }
  549.  
  550. void PMODE_restoreISR(int intno, SAVEINT *save)
  551. {
  552.     union REGS        r;
  553.     struct SREGS    s;
  554.  
  555.     segread(&s);
  556.     r.x.ax = 0x2507;        /* Set real and pmode vectors        */
  557.     r.x.cx = intno;
  558.     s.ds = FP_SEG(save->pmode_isr);
  559.     r.e.edx = (long)save->pmode_isr;
  560.     r.e.ebx = save->real_isr;
  561.     int86x(0x21, &r, &r, &s);
  562. }
  563.  
  564. void PMODE_setISR(int intno, void far *isr)
  565. {
  566.     union REGS      r;
  567.     struct SREGS    s;
  568.  
  569.     /* Once again in the code below, if the pointer to the ISR comes from
  570.      * some TASM'ed code it gets the segment value all wrong, so we force
  571.      * it to be the code segment here. Could well be a bug in FP_SEG() or
  572.      * something :-(
  573.      */
  574.  
  575.     segread(&s);
  576.     r.x.ax = 0x2506;        /* Hook real and protected vectors  */
  577.     r.x.cx = intno;
  578.     s.ds = FP_SEG(_ms_handler);
  579.     r.e.edx = (long)isr;
  580.     int86x(0x21, &r, &r, &s);
  581. }
  582.  
  583. #endif
  584.  
  585. /*-------------------------------------------------------------------------*/
  586. /* Intel Code Builder support.                                               */
  587. /* UNTESTED                                                                   */
  588. /*-------------------------------------------------------------------------*/
  589.  
  590. #if    defined(CODEBUILDER)
  591.  
  592. void * PMODE_mapLinearPointer(long base, unsigned limit)
  593. {
  594.     limit = limit;
  595.     return (void *)base;        /* Use linear address */
  596. }
  597.  
  598. void PMODE_freeLinearPointer(void *ptr)
  599. {
  600.     /* No free pointer */
  601.     ptr = ptr;
  602. }
  603.  
  604. /* This needs to be filled in with the remaining functions */
  605.  
  606. #endif
  607.  
  608. /*-------------------------------------------------------------------------*/
  609. /* Ergo OS/386 support.                                                       */
  610. /* UNTESTED                                                                */
  611. /*-------------------------------------------------------------------------*/
  612.  
  613. #ifdef ERGO386
  614.  
  615. /* Size must be <64K for this function */
  616. void * PMODE_mapLinearPointer(long base, unsigned limit)
  617. {
  618.     /* Limit will be restricted to less than 64k with this routine */
  619.  
  620.     union REGS r;
  621.  
  622.     /* Use create real window function */
  623.     r.x.ax = 0xE803;
  624.     r.x.cx = 0;                    /* cx:dx is limit */
  625.     r.x.dx = limit;
  626.     r.x.si = base >> 16;        /* si:bx is address */
  627.     r.x.bx = base & 0xFFFF;
  628.     int86(0x21, &r, &r);
  629.  
  630.     /* Construct pointer */
  631.     return MK_FP(r.x.ax, 0);
  632. }
  633.  
  634. void PMODE_freeLinearPointer(void *ptr)
  635. {
  636.     union REGS         r;
  637.     struct SREGS     s;
  638.     segread(&s);
  639.     s.es = FP_SEG(ptr);
  640.     r.h.ah = 0x49;
  641.     int86x(0x21, &r, &r, &s);
  642. }
  643.  
  644. /* This needs to be filled in with the remaining functions */
  645.  
  646. #endif
  647.  
  648. /*-------------------------------------------------------------------------*/
  649. /* Watcom C/C++ with Rational DOS/4GW support.                               */
  650. /*-------------------------------------------------------------------------*/
  651.  
  652. #ifdef    DOS4GW
  653.  
  654. #include <mem.h>
  655.  
  656. void * PMODE_mapLinearPointer(long base, unsigned limit)
  657. {
  658.     limit = limit;
  659.     return (void *)base;        /* Use linear address */
  660. }
  661.  
  662. void PMODE_freeLinearPointer(void *ptr)
  663. {
  664.     /* No need to do anything here */
  665.     ptr = ptr;
  666. }
  667.  
  668. void * PMODE_allocRealSeg(unsigned short size, unsigned long *segid,
  669.     unsigned *segment, unsigned *offset)
  670. {
  671.     union REGS        r;
  672.  
  673.     r.w.ax = 0x100;                    /* DPMI allocate DOS memory        */
  674.     r.w.bx = (size + 0xF) >> 4;        /* number of paragraphs         */
  675.     int386(0x31, &r, &r);
  676.     if (r.w.cflag) return NULL;        /* DPMI call failed                */
  677.  
  678.     *segment = r.w.ax;                /* Real mode segment            */
  679.     *offset = 0;
  680.     *segid = r.w.dx;                /* Protected mode selector        */
  681.  
  682.     /* Return a linear pointer to the memory */
  683.     return (void*)MK_PHYS(*segment,*offset);
  684. }
  685.  
  686. void PMODE_freeRealSeg(unsigned long segid)
  687. {
  688.     union REGS    r;
  689.  
  690.     r.w.ax = 0x101;                    /* DPMI free DOS memory            */
  691.     r.w.dx = segid;                    /* DX := selector from 0x100    */
  692.     int386(0x31, &r, &r);
  693. }
  694.  
  695. void * PMODE_createCSAlias(void *dataptr)
  696. {
  697.     return dataptr;
  698. }
  699.  
  700. void PMODE_freeCSAlias(void * alias)
  701. {
  702.     alias = alias;
  703. }
  704.  
  705. void far * PMODE_createDSAlias(void (*codeptr)())
  706. {
  707.     union REGS    r;
  708.  
  709.     r.w.ax = 0x0A;                    /* DPMI create alias descriptor    */
  710.     r.w.bx = FP_SEG(codeptr);
  711.     int386(0x31, &r, &r);
  712.     if (r.w.cflag) return NULL;        /* DPMI call failed                */
  713.  
  714.     return MK_FP(r.w.ax, FP_OFF(codeptr));
  715. }
  716.  
  717. void PMODE_freeDSAlias(void far * alias)
  718. {
  719.     union REGS    r;
  720.  
  721.     r.w.ax = 0x01;                    /* DPMI free descriptor            */
  722.     r.w.bx = FP_SEG(alias);            /* Selector to free                */
  723.     int386(0x31, &r, &r);
  724. }
  725.  
  726. typedef struct {
  727.     long    edi;
  728.     long    esi;
  729.     long    ebp;
  730.     long    reserved;
  731.     long    ebx;
  732.     long    edx;
  733.     long    ecx;
  734.     long    eax;
  735.     short    flags;
  736.     short    es,ds,fs,gs,ip,cs,sp,ss;
  737.     } _RMREGS;
  738.  
  739. #define IN(reg)     rmregs.e##reg = in->x.reg
  740. #define OUT(reg)    out->x.reg = rmregs.e##reg
  741.  
  742. int PMODE_int86(int intno, RMREGS *in, RMREGS *out)
  743. {
  744.     _RMREGS            rmregs;
  745.     union REGS        r;
  746.     struct SREGS    sr;
  747.  
  748.     memset(&rmregs, 0, sizeof(rmregs));
  749.     IN(ax); IN(bx); IN(cx); IN(dx); IN(si); IN(di);
  750.  
  751.     memset(&sr, 0, sizeof(sr));
  752.     r.w.ax = 0x300;                    /* DPMI issue real interrupt    */
  753.     r.h.bl = intno;
  754.     r.h.bh = 0;
  755.     r.w.cx = 0;
  756.     sr.es = FP_SEG(&rmregs);
  757.     r.x.edi = FP_OFF(&rmregs);
  758.     int386x(0x31, &r, &r, &sr);        /* Issue the interrupt            */
  759.  
  760.     OUT(ax); OUT(bx); OUT(cx); OUT(dx); OUT(si); OUT(di);
  761.     out->x.flags = rmregs.flags;
  762.     out->x.cflag = rmregs.flags & 0x1;
  763.     return out->x.ax;
  764. }
  765.  
  766. int PMODE_int86x(int intno, RMREGS *in, RMREGS *out,
  767.     RMSREGS *sregs)
  768. {
  769.     _RMREGS            rmregs;
  770.     union REGS        r;
  771.     struct SREGS    sr;
  772.  
  773.     memset(&rmregs, 0, sizeof(rmregs));
  774.     IN(ax); IN(bx); IN(cx); IN(dx); IN(si); IN(di);
  775.     rmregs.es = sregs->es;
  776.     rmregs.ds = sregs->ds;
  777.  
  778.     memset(&sr, 0, sizeof(sr));
  779.     r.w.ax = 0x300;                    /* DPMI issue real interrupt    */
  780.     r.h.bl = intno;
  781.     r.h.bh = 0;
  782.     r.w.cx = 0;
  783.     sr.es = FP_SEG(&rmregs);
  784.     r.x.edi = FP_OFF(&rmregs);
  785.     int386x(0x31, &r, &r, &sr);        /* Issue the interrupt */
  786.  
  787.     OUT(ax); OUT(bx); OUT(cx); OUT(dx); OUT(si); OUT(di);
  788.     sregs->es = rmregs.es;
  789.     sregs->cs = rmregs.cs;
  790.     sregs->ss = rmregs.ss;
  791.     sregs->ds = rmregs.ds;
  792.     out->x.flags = rmregs.flags;
  793.     out->x.cflag = rmregs.flags & 0x1;
  794.     return out->x.ax;
  795. }
  796.  
  797. int PMODE_installMouseHandler(int mask, void (cdecl far * handler)())
  798. {
  799.     union REGS        regs;
  800.     struct SREGS    sregs;
  801.  
  802.     segread(&sregs);
  803.     sregs.es = FP_SEG(handler);
  804.     regs.x.edx = FP_OFF(handler);
  805.     regs.x.ecx = mask;
  806.     regs.x.eax = 20;
  807.     int386x(0x33, ®s, ®s, &sregs);
  808.     return 1;
  809. }
  810.  
  811. /* No need to save the real mode ISR as DOS4GW always restores this for
  812.  * us.
  813.  */
  814.  
  815. void far * PMODE_getISR(int intno, SAVEINT *save)
  816. {
  817.     save->pmode_isr = (void far *)_dos_getvect(intno);
  818.     return save->pmode_isr;
  819. }
  820.  
  821. typedef void (interrupt far *intfp)();
  822.  
  823. void PMODE_restoreISR(int intno, SAVEINT *save)
  824. {
  825.     _dos_setvect(intno, (intfp)save->pmode_isr);
  826. }
  827.  
  828. void PMODE_setISR(int intno, void far *isr)
  829. {
  830.     _dos_setvect(intno, (intfp)isr);
  831. }
  832.  
  833. #endif
  834.  
  835. /*-------------------------------------------------------------------------*/
  836. /* DJGPP port of GNU C++ support.                                           */
  837. /* UNTESTED                                                                   */
  838. /*-------------------------------------------------------------------------*/
  839.  
  840. #ifdef DJGPP
  841.  
  842. void * PMODE_mapLinearPointer(long base, unsigned limit)
  843. {
  844.     limit = limit;
  845.     return (void *)(base + 0xE0000000);
  846. }
  847.  
  848. void PMODE_freeLinearPointer(void *ptr)
  849. {
  850.     /* No free pointer */
  851.     ptr = ptr;
  852. }
  853.  
  854. /* This needs to be filled in with the remaining functions */
  855.  
  856. #endif
  857.  
  858. /*-------------------------------------------------------------------------*/
  859. /* EMX port of GNU C++ support.                                               */
  860. /* UNTESTED                                                                   */
  861. /*-------------------------------------------------------------------------*/
  862.  
  863. #ifdef    EMX
  864.  
  865. void * PMODE_mapLinearPointer(long base, unsigned limit)
  866. {
  867.     limit = limit;
  868.     return (void *)base;
  869. }
  870.  
  871. void PMODE_freeLinearPointer(void *ptr)
  872. {
  873.     /* No free pointer */
  874.     ptr = ptr;
  875. }
  876.  
  877. /* This needs to be filled in with the remaining functions */
  878.  
  879. #endif
  880.