home *** CD-ROM | disk | FTP | other *** search
/ Super Net 1 / SUPERNET_1.iso / PC / OTROS / MSDOS / WATTCP / WNWATTCP.ZIP / SRC / DPMI.C < prev    next >
Encoding:
C/C++ Source or Header  |  1991-09-25  |  5.7 KB  |  251 lines

  1. #ifdef WINDOWS
  2. #include <dos.h>
  3. #include <windows.h>
  4. #include "dpmi.h"
  5.  
  6. #define MAKEP(seg, ofs) ((void far *)MAKELONG((ofs), (seg)))
  7.  
  8. static unsigned __0000H;
  9.  
  10.  
  11. dpmi_rmode_intr(unsigned intno, unsigned flags,
  12.     unsigned copywords, RMODE_CALL far *rmode_call)
  13. {
  14.     /* Copying won't work here - fail if they try it. */
  15.     if(copywords) return 0;
  16.  
  17.     /* To make DPMI reset the 8259's and A20 for real mode, set BH=1 */
  18.     if (flags) intno |= 0x100;
  19.  
  20.     _asm {
  21.         push di
  22.         mov ax, 0300h           /* simulate real-mode interrupt */
  23.         mov bx, word ptr intno  /* interrupt number, flags */
  24.         mov cx, 0        /* words to copy from pmode to rmode stack */
  25.         les di, dword ptr rmode_call  /* ES:DI = addr of rmode call struct */
  26.         int 31h                 /* call DPMI */
  27.         jc error
  28.         mov ax, 1               /* return TRUE */
  29.         jmp short done
  30.     }
  31. error:
  32.         _asm xor ax, ax         /* return FALSE */
  33. done:
  34.         _asm pop di
  35. }
  36.  
  37. unsigned
  38. dpmi_sel(void)
  39. {
  40.         asm {
  41.                 xor ax, ax
  42.                 mov cx, 1
  43.                 int 31h
  44.                 jc error
  45.                 jmp short done
  46.         }
  47. error:
  48.         asm xor ax, ax
  49. done:;
  50. }
  51.  
  52. dpmi_set_descriptor(unsigned pmodesel, DESCRIPTOR far *d)
  53. {
  54.         asm {
  55.                 push di
  56.                 mov ax, 0ch
  57.                 mov bx, word ptr pmodesel
  58.                 les di, dword ptr d
  59.                 int 31h
  60.                 jc error
  61.                 mov ax, 1
  62.                 jmp short done
  63.         }
  64. error:
  65.         asm xor ax, ax
  66. done:
  67.         asm pop di
  68. }
  69.  
  70. dpmi_get_descriptor(unsigned pmodesel, DESCRIPTOR far *d)
  71. {
  72.         asm {
  73.                 push di
  74.                 mov ax, 0bh
  75.                 mov bx, word ptr pmodesel
  76.                 les di, dword ptr d
  77.                 int 31h
  78.                 jc error
  79.                 mov ax, 1
  80.                 jmp short done
  81.         }
  82. error:
  83.         asm xor ax, ax
  84. done:
  85.         asm pop di
  86. }
  87.  
  88. void far (*dpmi_make_callback(void far (*p)(), RMODE_CALL far *rc))()
  89. {
  90.     _asm {
  91.     push ds
  92.     push si
  93.         push di
  94.         lds si, dword ptr p    /* pmode call-back procedure address */
  95.         les di, dword ptr rc    /* pmode address of static stuct to use */
  96.         mov ax, 0303h           /* allocate call-back address */
  97.         int 31h                 /* call DPMI */
  98.     pop di
  99.     pop si
  100.     pop ds
  101.         jc error
  102.         mov ax, dx        /* return rmode seg:ofs on success */
  103.     mov dx, cx
  104.     jmp short done
  105.     }
  106. error:
  107.     _asm xor ax, ax
  108.     _asm mov dx, ax
  109. done:;
  110. }
  111.  
  112. int
  113. dpmi_free_callback(void far (*p)())
  114. {
  115.     _asm {
  116.         mov    dx, word ptr p
  117.         mov    cx, word ptr p+2
  118.         mov    ax, 0304h
  119.         int    31h
  120.         mov    ax, 0
  121.         jc    done
  122.         inc    ax
  123.     }
  124. done:;
  125. }
  126.  
  127. unsigned
  128. verw(unsigned sel)
  129. {
  130.         asm mov ax, 1
  131.         asm verw sel
  132.         asm je short ok
  133.         asm xor ax, ax
  134. ok:;
  135. }
  136.  
  137. unsigned
  138. MapRealSeg(unsigned rpara, DWORD size, unsigned far *psel)
  139. {
  140.         DESCRIPTOR d;
  141.         unsigned long addr;
  142.         unsigned sel = dpmi_sel();
  143.         if(!sel)
  144.                 return 0;
  145.  
  146.         if(!verw(FP_SEG(psel)))
  147.                 return(490);
  148.  
  149.         dpmi_get_descriptor(FP_SEG(psel), &d);
  150.         d.limit = (unsigned)size - 1;
  151.         addr = ((unsigned long)rpara) << 4;
  152.         d.addr_lo = (unsigned)addr; d.addr_hi = (unsigned char)(addr >> 16);
  153.         d.res1 = d.addr_xhi = 0;
  154.         dpmi_set_descriptor(sel, &d);
  155.         *psel = sel;
  156.         return 0;
  157. }
  158.  
  159. void far *
  160. ProtToReal(void far *prot)
  161. {
  162.         unsigned long base = GetSelectorBase(FP_SEG(prot));
  163.         if(base >= 0x100000L)
  164.                 return NULL;
  165.         else
  166.                 return MAKEP(base >> 4, (base & 0x0f) + FP_OFF(prot));
  167. }
  168.  
  169. void far *
  170. map_real(void far *rptr, unsigned long size)
  171. {
  172.         unsigned seg, ofs, sel;
  173.  
  174.     /* If not running standard or enhanced, nothing more to do */
  175.     if(!(GetWinFlags() & WF_PMODE))
  176.         return rptr;
  177.  
  178.         if(!__0000H)
  179.                 __0000H = LOWORD(GetProcAddress(GetModuleHandle("KERNEL"), "__0000H"));
  180.  
  181.         seg = FP_SEG(rptr); ofs = FP_OFF(rptr);
  182.         if((seg < 0x1000) && ((ofs + size) < 0xffff))
  183.                 return(MAKEP(__0000H, (seg << 4) + ofs));
  184.         if(MapRealSeg(seg, size + ofs, &sel) != 0)
  185.                 return 0;
  186.         return(MAKEP(sel, ofs));
  187. }
  188.  
  189. void
  190. unmap_real(void far *p)
  191. {
  192.         unsigned sel = FP_SEG(p);
  193.  
  194.     /* If not running standard or enhanced, nothing more to do */
  195.     if(!(GetWinFlags() & WF_PMODE))
  196.         return;
  197.  
  198.         if(sel != __0000H) {
  199.                 asm {
  200.                         mov ax, 1
  201.                         mov bx, word ptr sel
  202.                         int 31h
  203.                         jc error
  204.                         mov ax, 1
  205.                         jmp short done
  206.                 }
  207.                 error:
  208.                         asm xor ax, ax
  209.                 done:;
  210.         }
  211. }
  212.  
  213. /*
  214. *    Replacement intr() function to perform a real-mode software
  215. *    interrupt under DPMI.
  216. */
  217. void
  218. pmode_intr(int intno, struct REGPACK _FAR *regs)
  219. {
  220.     RMODE_CALL pregs;
  221.     register RMODE_CALL *pp = &pregs;
  222.     register struct REGPACK far *rp = regs;
  223.  
  224.     pp->res1 = 0;
  225.     pp->flags = rp->r_flags;
  226.     pp->eax = rp->r_ax;
  227.     pp->ebx = rp->r_bx;
  228.     pp->ecx = rp->r_cx;
  229.     pp->edx = rp->r_dx;
  230.     pp->esi = rp->r_si;
  231.     pp->edi = rp->r_di;
  232.     pp->ebp = rp->r_bp;
  233.     pp->ds = rp->r_ds;
  234.     pp->es = rp->r_es;
  235.     pp->ss = pp->sp = 0;    /* 0:0 -> DPMI provides a 30-word stack */
  236.     pp->fs = pp->gs = pp->ds;
  237.     dpmi_rmode_intr(intno, 0, 0, (RMODE_CALL far *)pp);
  238.     rp->r_ax = pp->eax;
  239.     rp->r_bx = pp->ebx;
  240.     rp->r_cx = pp->ecx;
  241.     rp->r_dx = pp->edx;
  242.     rp->r_si = pp->esi;
  243.     rp->r_di = pp->edi;
  244.     rp->r_bp = pp->ebp;
  245.     rp->r_ds = pp->ds;
  246.     rp->r_es = pp->es;
  247.     rp->r_flags = pp->flags;
  248. }
  249.  
  250. #endif
  251.