home *** CD-ROM | disk | FTP | other *** search
/ Phoenix CD 2.0 / Phoenix_CD.cdr / 01e / msjall.zip / MSJV3-1.ZIP / LIM4.ALL < prev    next >
Text File  |  1988-03-08  |  24KB  |  758 lines

  1. Microsoft Systems Journal
  2. Volume 3; Issue 1; January, 1988
  3.  
  4. Code Listings For:
  5.  
  6.     LIM 4 Programs
  7.     pp. 67-80
  8.  
  9. Author(s): Marion Hansen and John Driscoll
  10. Title:     LIM 4.0: A Definition For the Next Generation of Expanded Memory
  11.  
  12.  
  13.  
  14. Figure 2
  15. ========
  16.  
  17. /* THIS IS THE MAIN PROGRAM FOR SAVSCR */
  18.  
  19. #include <c:\msc\include\dos.h>
  20. #include <c:\msc\include\memory.h>
  21. #include <c:\msc\include\stdio.h>
  22. #include <c:\emm\demo\emm.h>
  23.  
  24. /* set up size and base of video ram */
  25. #define VIDEO_RAM_SIZE 4000
  26. #define VIDEO_RAM_BASE 0XB8000000
  27. union REGS    inregs,    outregs;
  28. struct SREGS     segregs ;
  29.  
  30. char far *video_ram_ptr =  {VIDEO_RAM_BASE}; /* video start 
  31.                         address (CGA) */
  32. unsigned long int video_ram_size ={4000};    /* bytes in video ram */
  33. unsigned int emm_handle ;                    /* emm handle */
  34. char emm_device_name[] = "EMMXXXX0";         /* Device Nmae of EMM */
  35. char emm_handle_name[8] ="shared" ;          /* name for handle to 
  36.                         be shared */
  37. char far *emm_ptr;                           /* pointer to page 
  38.                                                 frame */
  39. char far *(*page_ptr) ;                      /* pointer to page in 
  40.                         the frame */
  41. int pages_needed = 4;
  42. struct log_phys {
  43.   int log_page_number;
  44.   int phys_page_number;
  45.        } current_pages [4] ;
  46. struct log_phys far *map_unmap_ptr ;
  47. int  result ;         /* result passed back from function calls */
  48.  
  49. main ()
  50. {
  51.    /***************************************************************/
  52.    /* Check for a expanded memory manager of 4.0 or greater.      */
  53.    /***************************************************************/
  54.  
  55.    check_emm_version_number();
  56.    
  57.    /***************************************************************/
  58.    /* Cet four pages of expanded memory.                          */
  59.    /***************************************************************/
  60.    result = get_expanded_memory(&emm_ptr, pages_needed, 
  61.         &emm_handle, emm_handle_name);
  62.    if (result != 0) exit(1);
  63.    
  64.    /***************************************************************/
  65.    /* Map in needed pages                                         */
  66.    /***************************************************************/
  67.  
  68.    result = map_unmap_multiple_pages (current_pages, emm_handle, 1);
  69.  
  70.    /***************************************************************/
  71.    /* Copy video screen to logical page 0.                        */
  72.    /***************************************************************/
  73.  
  74.    move_exchg_to_expanded(MOVE_MEMORY_REGION, /* Move to */
  75.                           video_ram_ptr,      /* conventional RAM */
  76.                           emm_handle,         /* handle number*/
  77.                           0,                  /* to physical page */
  78.                           video_ram_size);    /* the number bytes */
  79.    
  80.    /* make a null video screen at logical page 1 */
  81.    
  82. page_ptr = (emm_ptr + 0x4000);
  83. memset (page_ptr, 0, VIDEO_RAM_SIZE);
  84.  
  85.    /***************************************************************/
  86.    /* Unmap all of the pages so that they are proteced.           */
  87.    /***************************************************************/
  88.  
  89.    result = map_unmap_multiple_pages (current_pages, emm_handle, 0);
  90.  
  91.    /* exit to Dos */
  92.    
  93. }
  94.  
  95.  
  96. Figure 3
  97. ========
  98.  
  99.  
  100. /******************************************************************/
  101. /* This function checks to see if an expanded memory manager is   */
  102. /* and then checks to see if the version number is >= 4.0. It     */
  103. /* uses emm function GET VERSION NUMBER.                          */
  104. /******************************************************************/
  105.  
  106. int check_emm_version_number()
  107. {  
  108.    char *emm_device_name_ptr ;
  109.    
  110.    /***************************************************************/
  111.    /* Use the dos get interrupt function (0x35) to get pointer    */
  112.    /* at interrupt vector 0x67, and check for emm device name.    */
  113.    /***************************************************************/
  114.  
  115.    inregs.h.ah = 0x35;
  116.    inregs.h.al =EMM_INT;
  117.    intdosx(&inregs, &outregs, &segregs);
  118.    emm_device_name_ptr = (segregs.es * 65536) + 10;
  119.    if (memcmp(emm_device_name, emm_device_name_ptr,8) !=0)
  120.      {
  121.        printf("Expanded memory manager not present\n");
  122.        exit(1);
  123.      }
  124.  
  125.    /***************************************************************/
  126.    /* Now check for version number >= 4.0                         */    
  127.    /***************************************************************/
  128.  
  129.    inregs.h.ah = GET_VERSION ;  /* set funciton code */
  130.    int86(EMM_INT,&inregs,&outregs);
  131.    if (outregs.h.ah != 0) exit(1);
  132.    if ((outregs.h.ah == 0) & (outregs.h.al < 0x40))
  133.    {
  134.      printf("Expanded memory manager does not support LIM 4.0");
  135.      exit(1) ;
  136.    }  
  137. }
  138.  
  139.  
  140. Figure 4
  141. ========
  142.  
  143.  
  144. /******************************************************************/
  145. /* This function gets the amount of exapnded memory needed and    */
  146. /* returns a pointer to the page from in emm_ptr_ptr.  It also    */
  147. /* assigns a name to the handle. It will return a result of 
  148. /* non-zero if it fails.                                          */
  149. /******************************************************************/
  150.  
  151. int get_expanded_memory(emm_ptr_ptr, pages, emm_handle_ptr, name)
  152.  
  153. char *(*emm_ptr_ptr);    /* pointer to expanded memory page frame */
  154. int pages;               /* number of pages to allocate */
  155. unsigned int *emm_handle_ptr;  /* pointer to emm handle */
  156. char *name;
  157.  
  158. {
  159.    /* check for number of expanded memory pages requested */
  160.  
  161.    inregs.h.ah = GET_UNALLOCATED_PAGE_COUNT ;
  162.    int86(EMM_INT, &inregs, &outregs);
  163.    if (outregs.h.ah != 0) return(1);
  164.    if (outregs.x.bx < pages) return(2);
  165.  
  166.    /* allocate pages pages - Function */
  167.  
  168.    inregs.h.ah = ALLOCATE_PAGES ;   /* Get a handle and allocate */
  169.    inregs.x.bx = pages;             /* 4 logical pages           */ 
  170.    int86(EMM_INT, &inregs, &outregs);
  171.    if (outregs.h.ah != 0) return(3);
  172.    *emm_handle_ptr = outregs.x.dx ;
  173.  
  174.    /* get page frame segment address - Function 2 */
  175.  
  176.    inregs.h.ah = GET_FRAME_ADDRESS;
  177.    int86(EMM_INT, &inregs, &outregs);
  178.    if (outregs.h.ah != 0) return(4);
  179.    *emm_ptr_ptr = (unsigned long int) (outregs.x.bx *65536);
  180.    
  181.  
  182.    /* assign name to handle  - Function 20          */
  183.  
  184.    inregs.x.ax = SET_HANDLE_NAME ;
  185.    inregs.x.dx = *emm_handle_ptr ;
  186.    inregs.x.si = FP_OFF(name) ;
  187.    segregs.ds  = FP_SEG(name);
  188.    int86x(EMM_INT, &inregs, &outregs, &segregs);
  189.    if (outregs.h.ah != 0) return(5);
  190.  
  191.    return(0);
  192.  
  193. }
  194.  
  195.  
  196. Figure 5
  197. ========
  198.  
  199.  
  200. /******************************************************************/
  201. /* This function implements MAP/UNMAP MULTIPLE PAGES emm function */
  202. /******************************************************************/
  203.  
  204. int map_unmap_multiple_pages (log_phys_pages,handle,map_unmap)
  205.  
  206. struct log_phys *log_phys_pages ;  /* pointer to log_phys struct */
  207. unsigned int handle;               /* handle to map or unmap */
  208. unsigned int map_unmap;            /* 0 = map, 1 = unmap */
  209. {
  210.  int i ;
  211.  struct log_phys *temp_ptr;
  212.  
  213.  /* Map mulitple logical pages 0 -3 to logical pages 0 - 3 */
  214.  
  215.  temp_ptr = log_phys_pages;
  216.    
  217.  for (i=0 ; i<=3; i++) 
  218.  {
  219.    log_phys_pages->phys_page_number = i;
  220.    if (map_unmap == 1)
  221.     log_phys_pages->log_page_number = i;
  222.    else
  223.     log_phys_pages->log_page_number = 0xFFFF ; 
  224.  
  225.    log_phys_pages++ ;
  226.        
  227.  }
  228.  
  229.  inregs.x.ax = MAP_UNMAP_MULTIPLE_PAGES ;
  230.  inregs.x.dx = handle;
  231.  inregs.x.cx = 4;
  232.  inregs.x.si = FP_OFF(temp_ptr);
  233.  segregs.ds  = FP_SEG(temp_ptr);
  234.  int86x(EMM_INT,&inregs,&outregs,&segregs);
  235.  if (outregs.h.ah != 0) return(1);
  236.  return(0);
  237.  
  238.  
  239. Figure 6
  240. ========
  241.  
  242.  
  243.  
  244.  
  245. /******************************************************************/
  246. /* This function implements MOVE or EXCHANGE MEMORY REGION        */
  247. /* function to move or exchange conventional memory with expanded */
  248. /* memory pages                                                   */
  249. /******************************************************************/
  250.  
  251. int move_exchg_to_expanded(function_number, conv_buffer,  handle, 
  252.                            page, length)
  253. unsigned int function_number ; /* Move or Exchange*/
  254. char far *conv_buffer ;        /* conventional memory with */
  255. int handle;                    /* EMM memory associated with 
  256.                                   this handle */
  257. int page ;                     /* at this physical page */
  258. unsigned long int length;      /* and this many bytes */
  259.  
  260. {
  261. struct move_exchg 
  262.  {
  263.    unsigned long int region_length;
  264.    char source_type ;
  265.    unsigned int source_handle ;
  266.    unsigned int source_offset ;
  267.    unsigned int source_seg_page;
  268.    char dest_type;
  269.    unsigned int dest_handle;
  270.    unsigned int dest_offset;
  271.    unsigned int dest_seg_page;
  272.   } move_exchg_struct;
  273. struct move_exchg *move_exchg_ptr;  
  274.  
  275.   /* START OF FUNCTION CODE */
  276.  
  277.   move_exchg_struct.region_length  = length ;
  278.   move_exchg_struct.source_type    = 0;
  279.   move_exchg_struct.source_handle  = 0;
  280.   move_exchg_struct.source_offset   = FP_OFF(conv_buffer);
  281.   move_exchg_struct.source_seg_page = FP_SEG(conv_buffer);
  282.   move_exchg_struct.dest_type      = 1;
  283.   move_exchg_struct.dest_handle    = handle;
  284.   move_exchg_struct.dest_offset    = 0 ;
  285.   move_exchg_struct.dest_seg_page  = page;
  286.  
  287.   /* Setup structure to make int86x call */
  288.  
  289.   inregs.x.ax = function_number;
  290.   move_exchg_ptr = &move_exchg_struct;
  291.   inregs.x.si = FP_OFF(move_exchg_ptr);
  292.   segregs.ds  = FP_SEG(move_exchg_ptr);
  293.   int86x(EMM_INT, &inregs, &outregs, &segregs);
  294.   if (outregs.h.ah != 0) exit(1);
  295.  
  296.   return(outregs.x.ax) ;
  297.          
  298. }
  299.  
  300.  
  301. Figure 7
  302. ========
  303.  
  304.  
  305. /* THIS IS THE MAIN PROGRAM FOR SWPSCR */
  306.  
  307. #include <c:\msc\include\dos.h>
  308. #include <c:\msc\include\memory.h>
  309. #include <c:\msc\include\stdio.h>
  310. #include <c:\emm\demo\emm.h>
  311.  
  312. /* set up size and base of video ram */
  313.  
  314. #define VIDEO_RAM_SIZE 4000
  315. #define VIDEO_RAM_BASE 0XB8000000
  316. union REGS    inregs,    outregs;
  317. struct SREGS     segregs ;
  318.  
  319. char far *video_ram_ptr =  {VIDEO_RAM_BASE}; /* video  start address
  320.                                                 (CGA) */
  321. unsigned long int video_ram_size ={4000};    /* bytes in video ram */
  322. unsigned int emm_handle ;                    /* emm handle */
  323. char emm_device_name[] = "EMMXXXX0";         /* Device Nmae of EMM */
  324. char emm_handle_name[8] ="shared" ;          /* name for handle to be 
  325.                                                 shared */
  326. char far *emm_ptr;                           /* pointer to page 
  327.                                                 frame */
  328. char far *(*page_ptr) ;                      /* pointer to page in 
  329.                                                 the frame */
  330. int pages_needed = 4;
  331. struct log_phys {
  332.   int log_page_number;
  333.   int phys_page_number;
  334.        } current_pages [4] ;
  335. struct log_phys far *map_unmap_ptr ;
  336. int  result ;  /* result passed back from function calls */
  337.  
  338. main ()
  339. {
  340.    /***************************************************************/
  341.    /* Check for a expanded memory manager of 4.0 or greater.      */
  342.    /***************************************************************/
  343.  
  344.    check_emm_version_number();
  345.    
  346.    /***************************************************************/
  347.    /* Cet four pages of expanded memory.                          */
  348.    /***************************************************************/
  349.  
  350.    result = get_expanded_memory(&emm_ptr, pages_needed, &emm_handle, 
  351.                                 emm_handle_name);
  352.    if (result != 0) exit(1);
  353.    
  354.    /***************************************************************/
  355.    /* Map in needed pages                                         */
  356.    /***************************************************************/
  357.  
  358.    result = map_unmap_multiple_pages (current_pages, emm_handle, 1);
  359.  
  360.    /***************************************************************/
  361.    /* Copy video screen to logical page 0.                        */
  362.    /***************************************************************/
  363.  
  364.    move_exchg_to_expanded(MOVE_MEMORY_REGION, /* Move to convent- */
  365.                           video_ram_ptr,      /* ional ram area   */
  366.                           emm_handle,         /* handle number    */
  367.                           0,                  /* to physical page */
  368.                           video_ram_size);    /* the number bytes */
  369.    
  370.    
  371.  
  372.    /* make a null video screen at logical page 1 */
  373.  
  374.    page_ptr = (emm_ptr + 0x4000);
  375.    memset (page_ptr, 0, VIDEO_RAM_SIZE);
  376.  
  377.    /***************************************************************/
  378.    /* Unmap all of the pages so that they are proteced.           */
  379.    /***************************************************************/
  380.  
  381.    result = map_unmap_multiple_pages (current_pages, emm_handle, 0);
  382.  
  383.    /* exit to Dos */
  384.    
  385. }
  386.  
  387.  
  388. Figure 8
  389. ========
  390.  
  391.  
  392. /* THIS IS THE  MAIN PROGRAM FOR MAPCALL */
  393.  
  394. #include <c:\msc\include\dos.h>
  395. #include <c:\msc\include\memory.h>
  396. #include <c:\msc\include\stdio.h>
  397. #include <c:\emm\demo\emm.h>
  398.  
  399. /* set up size and base of video ram */
  400.  
  401. union REGS    inregs,    outregs;
  402. struct SREGS     segregs ;
  403.  
  404. unsigned int emm_handle ;
  405. char emm_device_name[] = "EMMXXXX0";      /* Device Name of EMM */
  406. char far emm_handle_name[8] ="mapcall";   /* name for handle */
  407. char far mod1_name[] =
  408.      "c:\\emm\\demo\\module1.exe\0";      /* name of modules to be */                                                      
  409. char far mod2_name[] =                    /* to be loaded */
  410.      "c:\\emm\\demo\\module2.exe\0";
  411. char far *emm_ptr ;
  412. char far *(*page_ptr) ;
  413. int pages_needed = 16 ;
  414.  
  415. struct log_phys {
  416.   int log_page_number;
  417.   int phys_page_number;
  418.        } ;
  419.  
  420. struct log_phys far current_pages[4];
  421.  
  422. struct log_phys far map_call_pages ;
  423.  
  424. int  result;      
  425.  
  426. main ()
  427. {
  428.  
  429.  
  430.    /***************************************************************/
  431.    /* Check for a expanded memory manager of 4.0 or greater.      */
  432.    /***************************************************************/
  433.  
  434.    check_emm_version_number();
  435.    
  436.    /***************************************************************/
  437.    /* Cet four pages of expanded memory.                          */
  438.    /***************************************************************/
  439.  
  440.    result = get_expanded_meory(&emm_ptr, pages_needed, &emm_handle,
  441.                                emm_handle_name);
  442.    if (result != 0) exit(1);
  443.  
  444.    /***************************************************************/
  445.    /* Map in needed pages                                         */
  446.    /***************************************************************/
  447.  
  448.    result = map_unmap_multiple_pages (current_pages, emm_handle, 1);
  449.    
  450.    /***************************************************************/
  451.    /* Load map and calls executeables into expanded memory        */
  452.    /***************************************************************/
  453.  
  454.    *page_ptr = emm_ptr;   /* Module 1 will be loaded into logical */
  455.    load_overlay(mod1_name, page_ptr, 0);   /* and physical page 0 */
  456.  
  457.    /***************************************************************/
  458.    /* Load module 2 into logical page 1 and physical page 1.      */
  459.    /***************************************************************/
  460.  
  461.    load_overlay(mod2_name, page_ptr, 1);
  462.    
  463.    /***************************************************************/
  464.    /* Unmap all pages. The map and call will map in the pages     */
  465.    /* requested and restore the present mapping.                  */
  466.    /***************************************************************/
  467.  
  468.    result = map_unmap_multiple_pages (current_pages, emm_handle, 0);
  469.    
  470.    /***************************************************************/
  471.    /* Do map and call to module in logical page 1. Map logical    */
  472.    /* page to physical page 0 and have current mapping context    */
  473.    /* restored on the return from the map and call.               */
  474.    /***************************************************************/
  475.  
  476.     map_call_pages.log_page_number  = 0;
  477.     map_call_pages.phys_page_number = 0;
  478.     
  479.     map_and_call(&map_call_pages, 1, ¤t_pages, 0, emm_handle);
  480.    
  481.    /***************************************************************/
  482.    /* release handle befor exiting.  This also ummaps any pages   */
  483.    /* that are mapped.                                            */
  484.    /***************************************************************/
  485.  
  486.    inregs.h.ah = DEALLOCATE_PAGES ;
  487.    inregs.x.dx = emm_handle ;
  488.    int86(EMM_INT, &inregs, &outregs);
  489.    
  490.    exit(0);
  491. }
  492.  
  493.  
  494. Figure 9
  495. ========
  496.  
  497.  
  498. /******************************************************************/
  499. /* This function implements ALTER PAGE MAP AND CALL  emm function */
  500. /******************************************************************/
  501.  
  502. int map_and_call(new_map_ptr, new_length, old_map_ptr, 
  503.                  old_length, handle)
  504. struct log_phys *new_map_ptr;
  505. char new_length;
  506. struct log_phys *old_map_ptr;
  507. char old_length;
  508. unsigned int handle;
  509. {
  510.   struct map_call_struct {
  511.      unsigned int offset_target_address ;
  512.      unsigned int seg_target_address ;
  513.      char new_page_map_length ;
  514.      unsigned int offset_new_page_map;
  515.      unsigned int seg_new_page_map ;
  516.      char old_page_map_length ;
  517.      unsigned int offset_old_page_map;
  518.      unsigned int seg_old_page_map ;
  519.    } map_call; 
  520.    struct map_call_struct *map_call_ptr;  
  521.  
  522.   map_call_ptr = &map_call ;
  523.   map_call.offset_target_address = 0 ;
  524.   map_call.seg_target_address    =0xd000;
  525.   map_call.new_page_map_length   = new_length;
  526.   map_call.offset_new_page_map   = FP_OFF(new_map_ptr);
  527.   map_call.seg_new_page_map      = FP_SEG(new_map_ptr);
  528.   map_call.old_page_map_length   = old_length;
  529.   map_call.offset_old_page_map   = FP_OFF(old_map_ptr);
  530.   map_call.seg_old_page_map      = FP_SEG(old_map_ptr);
  531.  
  532.   /****************************************************************/
  533.   /* Set up for alter page map and call function                  */
  534.   /****************************************************************/
  535.  
  536.   inregs.h.ah =0x56;
  537.   inregs.h.al = 0;
  538.   inregs.x.dx = handle ;
  539.   map_call_ptr = &map_call ;
  540.   inregs.x.si = FP_OFF(map_call_ptr);
  541.   segregs.ds = FP_SEG(map_call_ptr);
  542.   int86x(EMM_INT,&inregs,&outregs,&segregs);
  543.   if (outregs.h.ah != 0) return(1);
  544.  
  545.   return(0) ;
  546. }
  547.  
  548.  
  549. Figure 10
  550. ========
  551.  
  552.  
  553. /******************************************************************/
  554. /* This function implements the DOS load function 0x4b. It sets   */
  555. /* AL to 3 which cause the function to load the exe and apply a   */
  556. /* relocation factor to it, but it does not execute the file.     */
  557. /******************************************************************/
  558.  
  559. int load_overlay(load_file_name,relocation_ptr,page)
  560. char *load_file_name ;
  561. char *(*relocation_ptr);
  562. unsigned int page; /* physical page at which to load */
  563.   
  564. {
  565. struct reloc {
  566.   unsigned int load_seg;
  567.   unsigned int reloc_factor;
  568.   } reloc_struct;
  569.   struct reloc *reloc_struct_ptr;
  570.  
  571.   /* setup up structure to pass to load call */
  572.  
  573.   reloc_struct.load_seg = FP_SEG(*relocation_ptr) + (page * 0x400);
  574.   reloc_struct.reloc_factor = FP_SEG(*relocation_ptr) + 
  575.                                (page * 0x400); 
  576.   
  577.   /* Set up register structures for Intdos call */
  578.  
  579.   inregs.h.ah = 0x4B ;   /* Dos Exec function code */
  580.   inregs.h.al = 3;       /* load but do not execute */
  581.   inregs.x.dx  = FP_OFF(load_file_name);
  582.   segregs.ds   = FP_SEG(load_file_name);
  583.  
  584.   reloc_struct_ptr = &reloc_struct ;
  585.   inregs.x.bx  = FP_OFF(reloc_struct_ptr);
  586.   segregs.es  = FP_SEG(reloc_struct_ptr);
  587.  
  588.   intdosx(&inregs, &outregs, &segregs);
  589.  
  590. }
  591.  
  592.  
  593. Figure 11
  594. ========
  595.  
  596.  
  597. NAME start
  598.  
  599. ; Use the DOSSEG directive to insure that the code segment is the 
  600. ; first segment in the module. Since this piece of code will be 
  601. ; loaded in at the page frame at D000:0000H the map and call use 
  602. ; D000:0000H as the entry point.
  603.  
  604. DOSSEG
  605.  
  606. data SEGMENT PUBLIC 'DATA'
  607. Data  ends
  608.  
  609. CODE SEGMENT PUBLIC 'CODE'
  610.     ASSUME CS:CODE, DS:DATA
  611. start proc far
  612.      push    ds
  613.      PUSH    dx
  614.      mov     DX,data               ; get my data seg into ds
  615.      mov     ds,dx
  616.      pop     dx
  617.      mov     ah, 09                ; set function for dos 
  618.                                    ; display string
  619.      mov     dx, offset enter_msg
  620.      int    21H
  621.  
  622. ;    Use search for handel to find handle
  623.  
  624.      mov    si, offset handle_name
  625.      mov    ax, 5401H              ; set function to serch for 
  626.                                    ; named handle
  627.      int    67H                    ; invoke emm
  628.      or ah, ah
  629.      jnz exit
  630.  
  631. ; DX = handle number     
  632. ;
  633. ;  Set Register for map and call and call EMM with INT 67
  634.  
  635.      mov     si, offset map_call  
  636.      mov     al, 0                 ; indicate that values are pages
  637.      mov     ah, 56H               ; set function to map and call
  638.      int     67H                   ; invoke emm 
  639.      or ah, ah
  640.      jnz exit
  641.      
  642.      mov     ah, 09                ; set function for dos 
  643.                                    ; display string
  644.      mov     dx, offset exit_msg
  645.      int 21H
  646. exit:
  647.      pop     ds
  648.      ret
  649. start endp
  650. CODE ENDS
  651.  
  652. data SEGMENT PUBLIC 'DATA'
  653.  
  654. ; EQUATES
  655.  
  656. cr    equ  0Dh
  657. lf    equ  0AH
  658.  
  659. ; Structures
  660.  
  661. log_phys_map_struct      STRUC
  662.    log_page_number     DW ? 
  663.    phys_page_number    DW ? 
  664. log_phys_map_struct      ENDS
  665.  
  666. map_call_struct      STRUC
  667.     target_address      DD ?       ; Pointer to which EMM will  
  668.                                    ; transfer control 
  669.     new_page_map_length DB ?       ; number new pages to be mapped 
  670.                                    ; on call
  671.     new_page_map_ptr    DD ?       ; pointer to array of 
  672.                                    ; log_phys_map_struc
  673.     old_page_map_length DB ?       ; number of pages to mapped on 
  674.                                    ; return
  675.     old_page_map_ptr    DD ?       ; pointer to array of 
  676.                                    ; log_phys_map_struc
  677.     reseved             DW 4 DUP (?)
  678. map_call_struct ENDS
  679.  
  680. ; Data decalrations
  681.  
  682. new_map  log_phys_map_struct <1,1> ; maping befor call
  683. old_map  log_phys_map_struct <0,0> ; mapping after call
  684.  
  685. map_call  map_call_struct <0D0004000H,1,new_map,1,old_map>
  686.  
  687. handle_name db 'mapcall',0         ; handle name is asciz string                                            
  688. enter_msg   db 'Entering Module 1',cr,lf,'$'
  689. exit_msg    db 'Exiting Module 1',cr,lf,'$'
  690.  
  691. Data  ends
  692.  
  693. end  start
  694.  
  695.  
  696. Figure 12
  697. ========
  698.  
  699.  
  700. NAME start
  701. DOSSEG
  702.  
  703. data SEGMENT PUBLIC 'DATA'
  704. Data  ends
  705.  
  706. CODE SEGMENT PUBLIC 'CODE'
  707.     ASSUME CS:CODE, DS:DATA
  708. start proc far
  709.      push    ds
  710.      PUSH    dx
  711.      mov     DX,data               ; get my data seg into ds
  712.      mov     ds,dx
  713.      pop     dx
  714.      mov     ah, 09                ; set function for dos 
  715.                                    ; display string
  716.      mov     dx, offset enter_msg
  717.      int 21H
  718.      mov     ah, 09                ; set function for dos 
  719.                                    ; display string
  720.      mov     dx, offset exit_msg
  721.      int 21H
  722.      pop     ds
  723.      ret
  724. start endp
  725. CODE ENDS
  726.  
  727. data SEGMENT PUBLIC 'DATA'
  728. cr    equ  0Dh
  729. lf    equ  0AH
  730. enter_msg   db 'Entering Module 2',cr,lf,'$'
  731. exit_msg    db 'Exiting Module 2',cr,lf,'$'
  732.  
  733. Data  ends
  734.  
  735. end  start
  736.  
  737.  
  738. Figure 13
  739. ========
  740.  
  741.  
  742. /* emm.h */
  743.  
  744.  
  745. #define EMM_INT 0x67
  746. #define GET_UNALLOCATED_PAGE_COUNT 0x42
  747. #define ALLOCATE_PAGES             0x43
  748. #define DEALLOCATE_PAGES           0X45
  749. #define GET_VERSION                0x46
  750. #define GET_FRAME_ADDRESS          0x41
  751. #define SET_HANDLE_NAME            0x5301
  752. #define SEARCH_FOR_HANDLE_NAME     0x5401
  753. #define MOVE_MEMORY_REGION         0x5700
  754. #define EXCHANGE_MEMORY_REGION     0x5701
  755. #define MAP_UNMAP_MULTIPLE_PAGES   0x5000
  756.  
  757.