home *** CD-ROM | disk | FTP | other *** search
/ Microsoft Programmer's Library 1.3 / Microsoft-Programers-Library-v1.3.iso / sampcode / msj / msjv2_1 / ems / ems.c < prev   
Encoding:
C/C++ Source or Header  |  1989-02-28  |  9.1 KB  |  265 lines

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