home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / magazine / msysjour / vol07 / 06 / vxd / dpmishel.c < prev    next >
C/C++ Source or Header  |  1992-10-01  |  3KB  |  98 lines

  1. /* 
  2. DPMISHEL.C
  3. from Microsoft Systems Journal, October 1992
  4. Copyright (c) 1992 Andrew Schulman.  All rights reserved.
  5.  
  6. Shell to run a simple C program in protected mode under DPMI
  7. Must be compiled small model to use C run-time library
  8. Calls v86_main(), switches into protected mode, then calls pmode_main()
  9. */
  10.  
  11. #include <stdlib.h>
  12. #include <stdio.h>
  13. #include <dos.h>
  14.  
  15. #ifdef __BORLANDC__
  16. #define _dos_allocmem(x,y)  (allocmem(x,y) != -1)
  17. #endif
  18.  
  19. void _dos_exit(int retval)
  20. {
  21.     _asm mov ah, 04ch
  22.     _asm mov al, byte ptr retval
  23.     _asm int 21h
  24. }
  25.  
  26. static void fail(char *s) { puts(s); _dos_exit(1); }
  27.  
  28. // Call the DPMI Mode Detection function (INT 2Fh AX=1686h) to see
  29. // if we are *already* running in protected mode under DPMI.
  30. // See 3.1 DDK _Device Driver Adaptation Guide_, pp. 585-586
  31. int dpmi_present(void)
  32. {
  33.     unsigned _ax;
  34.     _asm mov ax, 1686h
  35.     _asm int 2Fh
  36.     _asm mov _ax, ax
  37.     return (! _ax);
  38. }
  39.  
  40. // Call the DPMI function for Obtaining the Real to Protected Mode
  41. // Switch Entry Point (INT 2Fh AX=1687h), to determine if DPMI is
  42. // available and, if so, switch into protected mode by calling
  43. // the Switch Entry Point.  See DPMI 0.9 spec.
  44. int dpmi_init(void)
  45. {
  46.     void (far *dpmi)();
  47.     unsigned hostdata_seg, hostdata_para, dpmi_flags;
  48.     _asm push si
  49.     _asm push di
  50.     _asm mov ax, 1687h           /* test for DPMI presence */
  51.     _asm int 2Fh
  52.     _asm and ax, ax
  53.     _asm jz gotdpmi              /* if (AX == 0) DPMI is present */
  54.     _asm jmp nodpmi
  55. gotdpmi:        
  56.     _asm mov dpmi_flags, bx
  57.     _asm mov hostdata_para, si   /* paras for DPMI host private data */
  58.     _asm mov word ptr dpmi, di
  59.     _asm mov word ptr dpmi+2, es /* DPMI protected-mode switch entry point */
  60.     _asm pop di
  61.     _asm pop si
  62.  
  63.     if (_dos_allocmem(hostdata_para, &hostdata_seg) != 0)
  64.         fail("can't allocate memory");
  65.     
  66.     dpmi_flags &= ~1;   /* this is a 16-bit protected-mode program */
  67.     
  68.     /* enter protected mode */
  69.     _asm mov ax, hostdata_seg
  70.     _asm mov es, ax
  71.     _asm mov ax, dpmi_flags
  72.     (*dpmi)();
  73.  
  74.     return 1;
  75. nodpmi:
  76.     return 0;
  77. }
  78.  
  79. extern int v86_main(int argc, char *argv[]);
  80. extern int pmode_main(int argc, char *argv[]);
  81.  
  82. main(int argc, char *argv[])
  83. {
  84.     int ret;
  85.     
  86.     v86_main(argc, argv); // call routine for any V86 mode stuff
  87.     
  88.     if (! dpmi_present())
  89.         if (! dpmi_init())
  90.             fail("This program requires DPMI");   
  91.         
  92.     /* now in protected mode */
  93.     ret = pmode_main(argc, argv);
  94.     flushall();     // flush all buffers before exiting
  95.     _dos_exit(ret);
  96. }
  97.  
  98.