home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / magazine / pcmagazi / 1991 / 11 / dpmimem.c < prev    next >
Text File  |  1991-05-10  |  4KB  |  155 lines

  1. /*
  2. DPMIMEM.C -- Demonstrates DPMI and Windows 3.0 DOS extender
  3.  
  4. Microsoft C: cl -AS dpmimem.c
  5. Turbo C:     tcc -ms dpmimem.c
  6.  
  7. Copyright (c) 1991 Ziff Communications Co.
  8.     PC Magazine * Andrew Schulman
  9. */
  10.  
  11. #ifdef __TURBOC__
  12. #pragma inline
  13. #define _asm                    asm
  14. #define _dos_allocmem(x,y)      (allocmem(x, y) != -1)
  15. #else
  16. #define MK_FP(seg, ofs) \
  17.     ((void far *) (((unsigned long) (seg) << 16) | (ofs)))
  18. #endif
  19.  
  20. #include <stdlib.h>
  21. #include <stdarg.h>
  22. #include <stdio.h>
  23. #include <time.h>
  24. #include <dos.h>
  25.  
  26. typedef enum { FALSE, TRUE } BOOL;
  27.  
  28. /* Call MS-DOS Terminate Process with Return Code function
  29.    (INT 21h AH=4Ch), in either real or protected mode */
  30. void dos_exit(unsigned err)
  31.     _asm mov al, err
  32.     _asm mov ah, 4Ch
  33.     _asm int 21h
  34. }
  35.  
  36. /* Call Windows Release Time-Slice function (INT 2Fh AX=1680h) */
  37. void win_yield(void)
  38. {
  39.     _asm mov ax, 1680h
  40.     _asm int 2Fh
  41. }
  42.  
  43. /* Call the Windows Enhanced Mode Install Check function
  44.    (INT 2Fh AX=1600h) */
  45. BOOL win_3enh(void)
  46. {
  47.     unsigned char vers;
  48.     _asm mov ax, 1600h
  49.     _asm int 2Fh
  50.     _asm mov vers, al
  51.     return (vers && (! (vers == 0x80 || vers == 1 || vers == 0xFF)));
  52. }
  53.  
  54. void fail(char *s)       { puts(s); dos_exit(1); }
  55.  
  56. /* Call the DPMI Mode Detection function (INT 2Fh AX=1686h) to
  57.    see if we are *already* running in protected mode under DPMI */
  58. BOOL dpmi_present(void)
  59. {
  60.     unsigned _ax;
  61.     _asm mov ax, 1686h
  62.     _asm int 2Fh
  63.     _asm mov _ax, ax
  64.     return (! _ax);
  65. }
  66.  
  67. /* Call the DPMI function for Obtaining the Real to Protected
  68.    Mode Switch Entry Point (INT 2Fh AX=1687h), to determine if
  69.    DPMI is available and, if so, switch into protected mode by
  70.    calling the Switch Entry Point */
  71. BOOL dpmi_init(void)
  72. {
  73.     unsigned rds, rcs;
  74.     void (far *dpmi)();
  75.     unsigned hostdata_seg, hostdata_para, dpmi_flags;
  76.     _asm mov ax, 1687h           // test for DPMI presence
  77.     _asm int 2Fh
  78.     _asm and ax, ax
  79.     _asm jnz nodpmi              // if (AX == 0) DPMI is present
  80.     _asm mov dpmi_flags, bx
  81.     _asm mov hostdata_para, si   // paras for DPMI host private data
  82.     _asm mov dpmi, di
  83.     _asm mov dpmi+2, es          // DPMI protected-mode switch entry point
  84.     _asm jmp short gotdpmi
  85. nodpmi:
  86.     return FALSE;
  87. gotdpmi:
  88.     if (_dos_allocmem(hostdata_para, &hostdata_seg) != 0)
  89.         fail("can't allocate memory");
  90.     
  91.     dpmi_flags &= ~1;   /* this is a 16-bit protected-mode program */
  92.     
  93.     _asm mov rds, ds
  94.     _asm mov rcs, cs
  95.     printf("DS=%04X CS=%04X in real mode\n", rds, rcs);
  96.     
  97.     /* enter protected mode */
  98.     _asm mov ax, hostdata_seg
  99.     _asm mov es, ax
  100.     _asm mov ax, dpmi_flags
  101.     (*dpmi)();
  102.  
  103.     /* now in protected mode */
  104.     _asm mov rds, ds
  105.     _asm mov rcs, cs
  106.     printf("DS=%04X CS=%04X in protected mode\n", rds, rcs);
  107.         
  108.     return TRUE;
  109. }
  110.  
  111. /* Call the MS-DOS Allocate Memory Block function (INT 21h AH=48h),
  112.    via the compiler's library function. The Windows DOS extender
  113.    provides INT 21h AH=48h in protected mode. */
  114. void far *my_malloc(unsigned bytes)
  115. {
  116.     unsigned seg;
  117.     return (_dos_allocmem(bytes >> 4, &seg)) ? 0 : MK_FP(seg, 0) ;
  118. }
  119.  
  120. #define SIZE        20480
  121.  
  122. main()
  123. {
  124.     unsigned long bytes = 0;
  125.     char far *fp;
  126.     time_t t1, t2;
  127.     
  128.     if (! dpmi_present())
  129.         if (! dpmi_init())
  130.             fail("This program requires DPMI");   
  131.         
  132.     /* now in protected mode */
  133.     
  134.     if (! win_3enh())
  135.         puts("Running under DPMI, but not under Windows 3.x enhanced mode");
  136.  
  137.     /* allocation loop */
  138.     time(&t1);
  139.     while (fp = my_malloc(SIZE))
  140.     {
  141.         *fp = 'x';
  142.         fp[SIZE-1] = 'y';
  143.         bytes += SIZE;
  144.         win_yield();
  145.     }
  146.     time(&t2);
  147.     
  148.     printf("Allocated %lu bytes in %lu seconds\n", bytes, t2 - t1);
  149.     printf("Press ENTER to release memory...");
  150.     fflush(stdout);
  151.     getchar();
  152.     dos_exit(0);
  153. }
  154.