home *** CD-ROM | disk | FTP | other *** search
/ SuperHack / SuperHack CD.bin / CODING / GRAPHICS / VOXRAY.ZIP / DPMISERV.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1995-07-10  |  8.1 KB  |  221 lines

  1. #include "os.h"
  2. #ifdef OS_DOS
  3.  
  4. #include <i86.h>
  5. #include <mem.h>
  6. #include <stdlib.h>
  7. #include <stdio.h>
  8. #include "dpmiserv.h"
  9.  
  10. void FatalError(char *msg)
  11. {
  12.     fprintf(stderr,"%s\n", msg);
  13.     exit(1);
  14. }
  15.  
  16. /*------------------------- DPMI interface routines -----------------------*/
  17.  
  18. void DPMI_allocRealSeg(int size,int *sel,int *r_seg)
  19. /****************************************************************************
  20. * Function:     DPMI_allocRealSeg
  21. * Parameters:   size    - Size of memory block to allocate
  22. *               sel     - Place to return protected mode selector
  23. *               r_seg   - Place to return real mode segment
  24. * Description:  Allocates a block of real mode memory using DPMI services.
  25. *               This routine returns both a protected mode selector and
  26. *               real mode segment for accessing the memory block.
  27. ****************************************************************************/
  28. {
  29.     union REGS      r;
  30.  
  31.     r.w.ax = 0x100;                 /* DPMI allocate DOS memory         */
  32.     r.w.bx = (size + 0xF) >> 4;     /* number of paragraphs             */
  33.     int386(0x31, &r, &r);
  34.     if (r.w.cflag)
  35.         FatalError("DPMI_allocRealSeg failed!");
  36.     *sel = r.w.dx;                  /* Protected mode selector          */
  37.     *r_seg = r.w.ax;                /* Real mode segment                */
  38. }
  39.  
  40. void DPMI_freeRealSeg(unsigned sel)
  41. /****************************************************************************
  42. * Function:     DPMI_allocRealSeg
  43. * Parameters:   sel - Protected mode selector of block to free
  44. * Description:  Frees a block of real mode memory.
  45. ****************************************************************************/
  46. {
  47.     union REGS  r;
  48.  
  49.     r.w.ax = 0x101;                 /* DPMI free DOS memory             */
  50.     r.w.dx = sel;                   /* DX := selector from 0x100        */
  51.     int386(0x31, &r, &r);
  52. }
  53. typedef struct {
  54.     long    edi;
  55.     long    esi;
  56.     long    ebp;
  57.     long    reserved;
  58.     long    ebx;
  59.     long    edx;
  60.     long    ecx;
  61.     long    eax;
  62.     short   flags;
  63.     short   es,ds,fs,gs,ip,cs,sp,ss;
  64.     } _RMREGS;
  65.  
  66. #define IN(reg)     rmregs.e##reg = in->x.reg
  67. #define OUT(reg)    out->x.reg = rmregs.e##reg
  68.  
  69. int DPMI_int86(int intno, RMREGS *in, RMREGS *out)
  70. /****************************************************************************
  71. * Function:     DPMI_int86
  72. * Parameters:   intno   - Interrupt number to issue
  73. *               in      - Pointer to structure for input registers
  74. *               out     - Pointer to structure for output registers
  75. * Returns:      Value returned by interrupt in AX
  76. * Description:  Issues a real mode interrupt using DPMI services.
  77. ****************************************************************************/
  78. {
  79.     _RMREGS         rmregs;
  80.     union REGS      r;
  81.     struct SREGS    sr;
  82.  
  83.     memset(&rmregs, 0, sizeof(rmregs));
  84.     IN(ax); IN(bx); IN(cx); IN(dx); IN(si); IN(di);
  85.  
  86.     segread(&sr);
  87.     r.w.ax = 0x300;                 /* DPMI issue real interrupt        */
  88.     r.h.bl = intno;
  89.     r.h.bh = 0;
  90.     r.w.cx = 0;
  91.     sr.es = sr.ds;
  92.     r.x.edi = (unsigned)&rmregs;
  93.     int386x(0x31, &r, &r, &sr);     /* Issue the interrupt              */
  94.  
  95.     OUT(ax); OUT(bx); OUT(cx); OUT(dx); OUT(si); OUT(di);
  96.     out->x.cflag = rmregs.flags & 0x1;
  97.     return out->x.ax;
  98. }
  99. int DPMI_int86x(int intno, RMREGS *in, RMREGS *out, RMSREGS *sregs)
  100. /****************************************************************************
  101. * Function:     DPMI_int86
  102. * Parameters:   intno   - Interrupt number to issue
  103. *               in      - Pointer to structure for input registers
  104. *               out     - Pointer to structure for output registers
  105. *               sregs   - Values to load into segment registers
  106. * Returns:      Value returned by interrupt in AX
  107. * Description:  Issues a real mode interrupt using DPMI services.
  108. ****************************************************************************/
  109. {
  110.     _RMREGS         rmregs;
  111.     union REGS      r;
  112.     struct SREGS    sr;
  113.  
  114.     memset(&rmregs, 0, sizeof(rmregs));
  115.     IN(ax); IN(bx); IN(cx); IN(dx); IN(si); IN(di);
  116.     rmregs.es = sregs->es;
  117.     rmregs.ds = sregs->ds;
  118.  
  119.     segread(&sr);
  120.     r.w.ax = 0x300;                 /* DPMI issue real interrupt        */
  121.     r.h.bl = intno;
  122.     r.h.bh = 0;
  123.     r.w.cx = 0;
  124.     sr.es = sr.ds;
  125.     r.x.edi = (unsigned)&rmregs;
  126.     int386x(0x31, &r, &r, &sr);     /* Issue the interrupt */
  127.  
  128.     OUT(ax); OUT(bx); OUT(cx); OUT(dx); OUT(si); OUT(di);
  129.     sregs->es = rmregs.es;
  130.     sregs->cs = rmregs.cs;
  131.     sregs->ss = rmregs.ss;
  132.     sregs->ds = rmregs.ds;
  133.     out->x.cflag = rmregs.flags & 0x1;
  134.     return out->x.ax;
  135. }
  136. int DPMI_allocSelector(void)
  137. /****************************************************************************
  138. * Function:     DPMI_allocSelector
  139. * Returns:      Newly allocated protected mode selector
  140. * Description:  Allocates a new protected mode selector using DPMI
  141. *               services. This selector has a base address and limit of 0.
  142. ****************************************************************************/
  143. {
  144.     int         sel;
  145.     union REGS  r;
  146.  
  147.     r.w.ax = 0;                     /* DPMI allocate selector           */
  148.     r.w.cx = 1;                     /* Allocate a single selector       */
  149.     int386(0x31, &r, &r);
  150.     if (r.x.cflag)
  151.         FatalError("DPMI_allocSelector() failed!");
  152.     sel = r.w.ax;
  153.  
  154.     r.w.ax = 9;                     /* DPMI set access rights           */
  155.     r.w.bx = sel;
  156.     r.w.cx = 0x8092;                /* 32 bit page granular             */
  157.     int386(0x31, &r, &r);
  158.     return sel;
  159. }
  160. long DPMI_mapPhysicalToLinear(long physAddr,long limit)
  161. /****************************************************************************
  162. * Function:     DPMI_mapPhysicalToLinear
  163. * Parameters:   physAddr    - Physical memory address to map
  164. *               limit       - Length-1 of physical memory region to map
  165. * Returns:      Starting linear address for mapped memory
  166. * Description:  Maps a section of physical memory into the linear address
  167. *               space of a process using DPMI calls. Note that this linear
  168. *               address cannot be used directly, but must be used as the
  169. *               base address for a selector.
  170. ****************************************************************************/
  171. {
  172.     union REGS  r;
  173.  
  174.     r.w.ax = 0x800;                 /* DPMI map physical to linear      */
  175.     r.w.bx = physAddr >> 16;
  176.     r.w.cx = physAddr & 0xFFFF;
  177.     r.w.si = limit >> 16;
  178.     r.w.di = limit & 0xFFFF;
  179.     int386(0x31, &r, &r);
  180.     if (r.x.cflag)
  181.         FatalError("DPMI_mapPhysicalToLinear() failed!");
  182.     return ((long)r.w.bx << 16) + r.w.cx;
  183. }
  184. void DPMI_setSelectorBase(int sel,long linAddr)
  185. /****************************************************************************
  186. * Function:     DPMI_setSelectorBase
  187. * Parameters:   sel     - Selector to change base address for
  188. *               linAddr - Linear address used for new base address
  189. * Description:  Sets the base address for the specified selector.
  190. ****************************************************************************/
  191. {
  192.     union REGS  r;
  193.  
  194.     r.w.ax = 7;                     /* DPMI set selector base address   */
  195.     r.w.bx = sel;
  196.     r.w.cx = linAddr >> 16;
  197.     r.w.dx = linAddr & 0xFFFF;
  198.     int386(0x31, &r, &r);
  199.     if (r.x.cflag)
  200.         FatalError("DPMI_setSelectorBase() failed!");
  201. }
  202. void DPMI_setSelectorLimit(int sel,long limit)
  203. /****************************************************************************
  204. * Function:     DPMI_setSelectorLimit
  205. * Parameters:   sel     - Selector to change limit for
  206. *               limit   - Limit-1 for the selector
  207. * Description:  Sets the memory limit for the specified selector.
  208. ****************************************************************************/
  209. {
  210.     union REGS  r;
  211.  
  212.     r.w.ax = 8;                     /* DPMI set selector limit          */
  213.     r.w.bx = sel;
  214.     r.w.cx = limit >> 16;
  215.     r.w.dx = limit & 0xFFFF;
  216.     int386(0x31, &r, &r);
  217.     if (r.x.cflag)
  218.         FatalError("DPMI_setSelectorLimit() failed!");
  219. }
  220. #endif
  221.