home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / doc / ems / demos / cexample / article.c next >
C/C++ Source or Header  |  1986-12-13  |  11KB  |  264 lines

  1. /* */
  2.  
  3. /*-------------------------------------------------------------------------*/
  4. /*                                                                         */
  5. /*                             M A I N                                     */
  6. /*                                                                         */
  7. /*                          P R O G R A M                                  */
  8. /*                                                                         */
  9. /*                       F I G U R E   T W O                               */
  10. /*                                                                         */
  11. /*-------------------------------------------------------------------------*/
  12.  
  13. #include <dos.h>
  14. #include <stdio.h>
  15.  
  16. #define EMM_INT 0x67                /*  EMM interrupt number  */
  17. #define GET_PAGE_FRAME_BASE 0x41    /*  EMM func = get page frame base address  */
  18. #define GET_FREE_COUNT 0x42         /*  EMM Func = get unallocated pages count  */
  19. #define ALLOCATE_PAGES 0x43         /*  EMM Func = allocates pages  */
  20. #define MAP_PAGES 0x44              /*  EMM Func = map pages  */
  21. #define DEALLOCATE_PAGES 0x45       /*  EMM Func = deallocate pages  */
  22. #define GET_INT_VECTOR 0x35         /*  DOS func = get interrupt vector  */
  23. #define DEVICE_NAME_LEN 8           /*  Number of chars in device driver name field  */
  24. #define VIDEO_RAM_SIZE 4000         /*  Total bytes in video RAM (char/attr)  */
  25. #define VIDEO_RAM_BASE 0xB0000000   /*  Video RAM start address (MDA) */
  26.  
  27. union REGS input_regs, output_regs; /*  Regs used for calls to EMM and DOS  */
  28. struct SREGS segment_regs;
  29. unsigned int emm_status;            /*  Status returned by EMM  */
  30.  
  31. main ()
  32.  
  33. {
  34. unsigned int i;
  35. long target_time, current_time;
  36. char *video_ram_ptr = {VIDEO_RAM_BASE}; /*  Pointer to video RAM  */
  37. unsigned int emm_handle;                /*  EMM handle  */
  38. char *expanded_memory_ptr;              /*  Pointer to expanded memory  */
  39.  
  40.  
  41. /*  Ensure that the Expanded Memory Manager software is installed on the 
  42.     user's system.  */
  43.  
  44.    detect_emm();
  45.  
  46.  
  47. /*  Get a page of expanded memory.  */
  48.  
  49.    get_expanded_memory_page (&expanded_memory_ptr, &emm_handle);
  50.  
  51.  
  52. /*  Copy the current video RAM contents to expanded memory.  */
  53.  
  54.    memcpy (expanded_memory_ptr, video_ram_ptr, VIDEO_RAM_SIZE);
  55.  
  56.  
  57. /*  Clear the screen to nulls.  */
  58.  
  59.    memset (video_ram_ptr, '\0', VIDEO_RAM_SIZE);
  60.  
  61.  
  62. /*  Delay for 1 second so the user can see the blanked screen.  */
  63.  
  64.    time (¤t_time);
  65.    target_time = current_time + 1;
  66.    while (current_time < target_time)
  67.     {
  68.      time (¤t_time);
  69.     }
  70.  
  71.  
  72. /*  Restore the video RAM contents from expanded memory.  */
  73.  
  74.    memcpy (video_ram_ptr, expanded_memory_ptr, VIDEO_RAM_SIZE);
  75.  
  76.  
  77. /*  Deallocate the expanded memory page  */
  78.  
  79.    release_expanded_memory_page (emm_handle);
  80.  
  81.  
  82.    exit(0);
  83. }
  84.  
  85. /* */
  86.  
  87. /*-------------------------------------------------------------------------*/
  88. /*                                                                         */
  89. /*                       S U B R O U T I N E                               */
  90. /*                                                                         */
  91. /*           G E T _ E X P A N D E D _ M E M O R Y _ P A G E               */
  92. /*                                                                         */
  93. /*                     F I G U R E   T H R E E                             */
  94. /*                                                                         */
  95. /*-------------------------------------------------------------------------*/
  96.  
  97. get_expanded_memory_page (expanded_memory_ptr_ptr, emm_handle_ptr)
  98.  
  99. unsigned int *emm_handle_ptr;     /*  16 bit handle returned by EMM  */
  100. char *(*expanded_memory_ptr_ptr); /*  Pointer to expanded memory page  */
  101.  
  102. {
  103. unsigned int page_frame_base;     /*  Expanded memory page frame base  */
  104. unsigned int physical_page = {0}; /*  Physical page number  */
  105.  
  106.  
  107. /*  Get unallocated pages count.  */
  108.  
  109.    input_regs.h.ah = GET_FREE_COUNT;    /*  EMM function  */
  110.    int86x (EMM_INT, &input_regs, &output_regs, &segment_regs);
  111.    emm_status = output_regs.h.ah;
  112.    check_status(emm_status);            /*  Check for errors  */
  113.    if (output_regs.x.bx < 1)            /*  Check unallocated page count  */
  114.     {
  115.      printf ("\x07Abort: insufficient unallocated expanded memory pages\n");
  116.      exit(0);
  117.     }
  118.  
  119.  
  120. /*  Allocate the specified number of pages.  */
  121.  
  122.    input_regs.h.ah = ALLOCATE_PAGES;     /*  EMM function  */
  123.    input_regs.x.bx = 1;                  /*  Number of pages to allocate  */
  124.    int86x (EMM_INT, &input_regs, &output_regs, &segment_regs);
  125.    emm_status = output_regs.h.ah;
  126.    check_status(emm_status);             /*  Check for errors  */
  127.    *emm_handle_ptr = output_regs.x.dx;   /*  Get EMM handle  */
  128.  
  129.  
  130. /*  Map the logical page into physical page 0.  */
  131.  
  132.    input_regs.h.ah = MAP_PAGES;          /*  EMM function  */
  133.    input_regs.h.al = 0;                  /*  Logical page number  */
  134.    input_regs.x.bx = physical_page;      /*  Physical page number  */
  135.    input_regs.x.dx = *emm_handle_ptr;    /*  EMM handle  */
  136.    int86x (EMM_INT, &input_regs, &output_regs, &segment_regs);
  137.    emm_status = output_regs.h.ah;
  138.    check_status(emm_status);             /*  Check for errors  */
  139.  
  140.  
  141. /*  Determine the page frame address.   */
  142.  
  143.    input_regs.h.ah = GET_PAGE_FRAME_BASE; /*  EMM function  */
  144.    int86x (EMM_INT, &input_regs, &output_regs, &segment_regs);
  145.    emm_status = output_regs.h.ah;
  146.    check_status(emm_status);              /*  Check for errors  */
  147.    *expanded_memory_ptr_ptr = 
  148.      (output_regs.x.bx * 65536)
  149.      + (physical_page * 16 * 1024);       /*  Set the expanded memory ptr  */
  150. }
  151.  
  152. /* */
  153.  
  154. /*-------------------------------------------------------------------------*/
  155. /*                                                                         */
  156. /*                      S U B R O U T I N E                                */
  157. /*                                                                         */
  158. /*       R E L E A S E _ E X P A N D E D _ M E M O R Y _ P A G E           */
  159. /*                                                                         */
  160. /*                     F I G U R E   F O U R                               */
  161. /*                                                                         */
  162. /*-------------------------------------------------------------------------*/
  163.  
  164. release_expanded_memory_page (emm_handle)
  165.  
  166. unsigned int emm_handle;      /*  Handle identifying which page 
  167.                                   set to deallocate  */
  168. {
  169.  
  170. /*  Release the expanded memory pages by deallocating the handle 
  171.     associated with those pages.  */
  172.   
  173.    input_regs.h.ah = DEALLOCATE_PAGES;  /*  EMM function  */
  174.    input_regs.x.dx = emm_handle;        /*  EMM handle passed in DX  */
  175.    int86x (EMM_INT, &input_regs, &output_regs, &segment_regs);
  176.    emm_status = output_regs.h.ah;
  177.    check_status(emm_status);            /*  Check for errors  */
  178.  
  179. /* */
  180.  
  181. /*-------------------------------------------------------------------------*/
  182. /*                                                                         */
  183. /*                      S U B R O U T I N E                                */
  184. /*                                                                         */
  185. /*                    C H E C K _ S T A T U S                              */
  186. /*                                                                         */
  187. /*                     F I G U R E   F I V E                               */
  188. /*                                                                         */
  189. /*-------------------------------------------------------------------------*/
  190.  
  191. check_status (emm_status)
  192. unsigned int emm_status;
  193. {
  194. static char *emm_error_strings[] = {
  195.    "no error",
  196.    "EMM software malfunction",
  197.    "EMM hardware malfunction",
  198.    "RESERVED",
  199.    "Invalid EMM handle",
  200.    "Invalid EMM function code",
  201.    "All EMM handles being used",
  202.    "Save/restore page mapping context error",
  203.    "Not enough expanded memory pages",
  204.    "Not enough unallocated pages",
  205.    "Can not allocate zero pages",
  206.    "Logical page out of range",
  207.    "Physical page out of range",
  208.    "Page mapping hardware state save area full",
  209.    "Page mapping hardware state save area already has handle",
  210.    "No handle associated with the page mapping hardware state save area",
  211.    "Invalid subfunction"
  212.  };
  213.  
  214. /*  IF EMM error, THEN print error message and EXIT  */
  215.  
  216.    if (emm_status != 0)                    /*  IF EMM error...  */
  217.     {
  218.       emm_status -= 0x7F;                  /*  Make error code zero-based  */
  219.       printf ("\x07Abort: EMM error = ");  /*  Issue error prefix  */
  220.       printf ("%s\n", emm_error_strings[emm_status]);
  221.                                            /*  Issue actual error message  */
  222.       exit(0);                             /*  And then exit to DOS  */
  223.     }
  224. }
  225.  
  226. /* */
  227.  
  228. /*-------------------------------------------------------------------------*/
  229. /*                                                                         */
  230. /*                          S U B R O U T I N E                            */
  231. /*                                                                         */
  232. /*                          D E T E C T _ E M M                            */
  233. /*                                                                         */
  234. /*                          F I G U R E   S I X                            */
  235. /*                                                                         */
  236. /*-------------------------------------------------------------------------*/
  237.  
  238. detect_emm ()
  239.  
  240. {
  241. static char EMM_device_name [DEVICE_NAME_LEN] = {"EMMXXXX0"};
  242. char *int_67_device_name_ptr;
  243.  
  244.  
  245. /*  Determine the address of the routine associated with INT 67 hex.  */
  246.  
  247.    input_regs.h.ah = GET_INT_VECTOR;  /*  DOS function  */
  248.    input_regs.h.al = EMM_INT;         /*  EMM interrupt number  */
  249.    intdosx (&input_regs, &output_regs, &segment_regs);
  250.    int_67_device_name_ptr = 
  251.    (segment_regs.es * 65536) + 10;    /*  Create ptr to device name field  */
  252.  
  253.  
  254. /*  Compare the device name with the known EMM device name.  */
  255.  
  256.    if (memcmp (EMM_device_name, int_67_device_name_ptr, DEVICE_NAME_LEN) != 0)
  257.     {
  258.       printf ("\x07Abort: EMM device driver not installed\n");
  259.       exit(0);
  260.     }  
  261.  
  262.