home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / doc / ems / demos / asmexamp / kernal.asm next >
Assembly Source File  |  1988-04-22  |  19KB  |  444 lines

  1. PAGE 60, 132
  2. NAME    expanded_memory_dispatcher_kernal
  3.  
  4. ;-----------------------------------------------------------------------------;
  5. ;   Placing null segment declarations at this point forces the segment        ;
  6. ;   order for the remainder of the program.                                   ;
  7. ;-----------------------------------------------------------------------------;
  8.  
  9. CODE    SEGMENT PARA PUBLIC 'CODE'
  10. ORG    100h
  11. CODE    ENDS
  12.  
  13. DATA    SEGMENT PARA PUBLIC 'DATA'
  14. DATA    ENDS
  15.  
  16. STACK    SEGMENT PARA 'STACK'
  17. STACK    ENDS
  18.  
  19.  
  20. PAGE
  21. ;-----------------------------------------------------------------------------;
  22. ;                     E Q U A T E S   &   M A C R O S                         ;
  23. ;-----------------------------------------------------------------------------;
  24. cr    EQU    0Dh
  25. lf    EQU    0Ah
  26.  
  27. DISPLAY    MACRO        msg
  28.     MOV        AH, 09h
  29.     LEA        DX, msg
  30.     INT        21h
  31. ENDM
  32.  
  33.  
  34. PAGE
  35. ;-----------------------------------------------------------------------------;
  36. ;         D A T A   S E G M E N T    F O R   T H E   K E R N A L              ;
  37. ;-----------------------------------------------------------------------------;
  38.  
  39. DATA            SEGMENT PARA PUBLIC 'DATA'
  40.  
  41. ;-----------------------------------------------------------------------------;
  42. ;   Messages.                                                                 ;
  43. ;-----------------------------------------------------------------------------;
  44. signon_msg        DB    'Intel Expanded Memory Code Load & Execute Demo', cr, lf
  45.             DB    '.  ', cr, lf, '$'
  46. emm_check_msg        DB    '.  Checking for EMM loaded', cr, lf, '$'
  47. emm_not_loaded_msg    DB    '.  EMM not loaded', cr, lf, '$'
  48. alloc_exp_mem_msg    DB    '.  Allocating & mapping expanded memory', cr, lf, '$'
  49. load_overlay_msg    DB    '.  Loading overlay into expanded memory', cr, lf, '$'
  50. calling_overlay_msg    DB    '.  Calling loaded code in expanded memory', cr, lf, '$'
  51. dealloc_exp_mem_msg    DB    '.  Deallocating expanded memory', cr, lf, '$'
  52. emm_err_msg        DB    '.  EMM error occurred', cr, lf, '$'
  53.  
  54. ;-----------------------------------------------------------------------------;
  55. ;   Name of pseudo-overlay.                                                   ;
  56. ;-----------------------------------------------------------------------------;
  57. pseudo_overlay_name    DB    'OVERLAY.EXE', 0
  58.  
  59. ;-----------------------------------------------------------------------------;
  60. ;   Standard EMM device name.                                                 ;
  61. ;-----------------------------------------------------------------------------;
  62. EMM_device_name        DB    'EMMXXXX0'
  63.  
  64. ;-----------------------------------------------------------------------------;
  65. ;   Miscellaneous temps.                                                      ;
  66. ;-----------------------------------------------------------------------------;
  67. exp_mem_segment        DW    ?
  68. EMM_handle        DW    ?
  69. com_file_entry_point    DD    ?
  70.  
  71. ;-----------------------------------------------------------------------------;
  72. ;   Structure definition for a DOS "load overlay" parameter block.            ;
  73. ;-----------------------------------------------------------------------------;
  74. parm_block_struct    STRUC
  75.     load_segment    DW    ?
  76.     reloc_factor    DW    ?
  77. parm_block_struct    ENDS
  78. parm_block        parm_block_struct <>
  79.  
  80. DATA            ENDS
  81.  
  82.  
  83. PAGE
  84. ;-----------------------------------------------------------------------------;
  85. ;         C O D E   S E G M E N T    F O R   T H E   K E R N A L              ;
  86. ;-----------------------------------------------------------------------------;
  87.  
  88. CODE    SEGMENT PARA PUBLIC 'CODE'
  89.  
  90. ASSUME    CS:CODE, DS:DATA, ES:NOTHING, SS:STACK
  91.  
  92. ;-----------------------------------------------------------------------------;
  93. ;   We will establish a convention in which the first object located at the   ;
  94. ;   expanded memory page frame will be a data structure which describes       ;
  95. ;   the data & extra segments of the loaded overlay, the number of procedure  ;
  96. ;   entry points in the loaded overlay, and a list of far pointers to         ;
  97. ;   each of the procedures contained in the pseudo-overlay which is to be     ;
  98. ;   loaded in expanded memory.  The developer must establish a convention     ;
  99. ;   for the sequence of the far pointers and what the procedures they point   ;
  100. ;   to do.  Other information could be passed in this structure as well.      ;
  101. ;   Such as, number and types of parameters which are be passed by the        ;
  102. ;   calling procedures to the called procedures in the pseudo-overlay.        ;
  103. ;                                                                             ;
  104. ;   This example uses a literal to determine the maximum number of far        ;
  105. ;   pointers which may be passed.  To allocate additional space for a larger  ;
  106. ;   number of entries, simply increase the value of max_proc_entries.  The    ;
  107. ;   example assumes a MAXIMUM of 64 entries can be returned.                  ;
  108. ;-----------------------------------------------------------------------------;
  109.  
  110. max_proc_entries        EQU    64
  111.  
  112. pseudo_overlay_entry_struct    STRUC
  113.     proc_data_segment    DW    ?
  114.     proc_extra_segment    DW    ?
  115.     proc_entry_count    DW    ?
  116.     proc_entry_ptr        DD max_proc_entries DUP (?)
  117. pseudo_overlay_entry_struct    ENDS
  118.  
  119.  
  120. PAGE
  121. ;-----------------------------------------------------------------------------;
  122. ;   This is an example of how a set of procedures may be loaded into          ;
  123. ;   expanded memory and invoked any time it is desired.  The procedures       ;
  124. ;   contained in the loaded program may be called at any time the main        ;
  125. ;   program desires to do so.  In this example, the program will be a         ;
  126. ;   collection of four procedures written in assembler.  They could also be   ;
  127. ;   written in a high level language provided that the language is able to    ;
  128. ;   generate COM style files with the initialization code located at offset   ;
  129. ;   100h.  The language must also be able to perform a far return because     ;
  130. ;   the calls made to the loaded procedures are inter-segment calls.          ;
  131. ;                                                                             ;
  132. ;   We will refer to this collection of loaded procedures as a                ;
  133. ;   pseudo-overlay.  The program which loads the pseudo-overlay will be       ;
  134. ;   referred to as the kernal.  This example kernal loads only a single       ;
  135. ;   pseudo-overlay and immediately invokes all the procedures contained in    ;
  136. ;   the overlay.  A programmer could as easily load as many overlays as       ;
  137. ;   desired simply by allocating additional pages, mapping in four or fewer   ;
  138. ;   pages (depending on the length of the pseudo-overlay code), and then      ;
  139. ;   loading the pseudo-overlay.  A key point to remember is that the          ;
  140. ;   maximum size of the expanded memory page frame is 64K bytes.  So, the     ;
  141. ;   overlays loaded cannot exceed 64K bytes in length.  However, the          ;
  142. ;   programmer can load as many of them as is desired by allocating the       ;
  143. ;   expanded memory required up to a maximum of 8M bytes.  Another key point  ;
  144. ;   to remember is that although the DOS "load & execute" function was used   ;
  145. ;   to load the overlays, the code and any data which was loaded remains      ;
  146. ;   present after the load takes place.  The procedures contained in the      ;
  147. ;   pseudo-overlay may be accessed by the use of the list of pointers         ;
  148. ;   returned to the kernal.                                                   ;
  149. ;                                                                             ;
  150. ;   What functions are contained in the overlays is left as an excercise of   ;
  151. ;   the fertile imaginations of developers.                                   ;
  152. ;-----------------------------------------------------------------------------;
  153.  
  154. main    PROC    NEAR
  155.     ;---------------------------------------------------------------------;
  156.     ;   Initialization                                                    ;
  157.     ;---------------------------------------------------------------------;
  158.     MOV        AX, DATA                
  159.     MOV        DS, AX
  160.     DISPLAY        signon_msg
  161.  
  162. check_for_emm_loaded:
  163.     ;---------------------------------------------------------------------;
  164.     ;   Use the "interrupt vector" technique to determine whether         ;
  165.     ;   EMM is loaded.                                                    ;
  166.     ;---------------------------------------------------------------------;
  167.     DISPLAY        emm_check_msg
  168.     CALL        test_for_EMM                
  169.     JE        get_emm_page_frame            
  170.     DISPLAY        emm_not_loaded_msg
  171.     JMP        exit                
  172.  
  173. get_emm_page_frame:
  174.     ;---------------------------------------------------------------------;
  175.     ;   Allocating expanded memory for overlay.                           ;
  176.     ;---------------------------------------------------------------------;
  177.     DISPLAY        alloc_exp_mem_msg
  178.  
  179.     ;---------------------------------------------------------------------;
  180.     ;   Get the page frame base address from EMM.                         ;
  181.     ;---------------------------------------------------------------------;
  182.     MOV        AH, 41h                    
  183.     INT        67h                    
  184.     OR        AH, AH
  185.     JZ        allocate_64K
  186.     JMP        emm_err_exit
  187.  
  188. allocate_64K:
  189.     ;---------------------------------------------------------------------;
  190.     ;   Allocate 4 pages of expanded memory for this example.  More can   ;
  191.     ;   be allocated depending on the number of overlays to be loaded.    ;
  192.     ;   Actually, in the case of this example, only a single page is      ;
  193.     ;   required because the example pseudo-overlay is extremely small.   ;
  194.     ;---------------------------------------------------------------------;
  195.     MOV        exp_mem_segment, BX            
  196.     MOV        AH, 43h                    
  197.     MOV        BX, 4                    
  198.     INT        67h                    
  199.     OR        AH, AH                    
  200.     JZ        map_64K                    
  201.     JMP        emm_err_exit                
  202.                             
  203. map_64K:
  204.     ;---------------------------------------------------------------------;
  205.     ;   Map in the first 4 logical pages at physical pages 0 thru 3.      ;
  206.     ;      logical page 0 at physical page 0                              ;
  207.     ;      logical page 1 at physical page 1                              ;
  208.     ;      logical page 2 at physical page 2                              ;
  209.     ;      logical page 3 at physical page 3                              ;
  210.     ;   If additional overlays were required, each overlay would be       ;
  211.     ;   loaded after mapping and a new set of logical pages would be      ;
  212.     ;   mapped at the same phisical pages.                                ;
  213.     ;---------------------------------------------------------------------;
  214.     MOV        EMM_handle, DX                
  215.     MOV        CX, 4                    
  216. map_pages_loop:                        
  217.     MOV        AH, 44h                    
  218.     MOV        BX, CX                    
  219.     DEC        BX                    
  220.     MOV        AL, BL                    
  221.     MOV        DX, EMM_handle                
  222.     INT        67h                    
  223.     OR        AH, AH                    
  224.     LOOPE        map_pages_loop                
  225.     JE        initialize_load_structure
  226.     JMP        emm_err_exit
  227.  
  228. initialize_load_structure:
  229.     ;---------------------------------------------------------------------;
  230.     ;   Load the overlay.                                                 ;
  231.     ;---------------------------------------------------------------------;
  232.     DISPLAY        load_overlay_msg
  233.  
  234.     ;---------------------------------------------------------------------;
  235.     ;   Initialize pseudo-overlay environment and procedure pointer area. ;
  236.     ;   This structure begins at the page frame segment address.          ;
  237.     ;---------------------------------------------------------------------;
  238.     MOV        ES, exp_mem_segment            
  239.     MOV        DI, 0                    
  240.     MOV        CX, (SIZE pseudo_overlay_entry_struct)    
  241.     MOV        AL, 0                    
  242.     REP        STOSB
  243.  
  244.     ;---------------------------------------------------------------------;
  245.     ;   Compute the load address within expanded memory for the overlay.  ;
  246.     ;   The address is rounded up to the next higher paragraph boundary   ;
  247.     ;   immediately following the pseudo-overlay environment & procedure  ;
  248.     ;   pointer structure.  This computation takes into account the       ;
  249.     ;   maximum number of procedure entry points which the pseudo-overlay ;
  250.     ;   is going to return to this program.                               ;
  251.     ;---------------------------------------------------------------------;
  252.     MOV        AX, (SIZE pseudo_overlay_entry_struct)    
  253.     ADD        AX, 000Fh                
  254.     AND        AX, 0FFF0h                
  255.     MOV        CX, 4                    
  256.     SHR        AX, CL                    
  257.     ADD        AX, exp_mem_segment            
  258.     MOV        parm_block.load_segment, AX        
  259.     MOV        parm_block.reloc_factor, AX        
  260.  
  261.     ;---------------------------------------------------------------------;
  262.     ;   Build the entry point for the .COM file in this example.          ;
  263.     ;---------------------------------------------------------------------;
  264.     MOV        WORD PTR com_file_entry_point[0], 100h    
  265.     MOV        WORD PTR com_file_entry_point[2], AX
  266.  
  267.     ;---------------------------------------------------------------------;
  268.     ;   Load the pseudo-overlay using the DOS "load overlay" function.    ;
  269.     ;---------------------------------------------------------------------;
  270.     MOV        AH, 4Bh                    
  271.     MOV        AL, 03h                    
  272.     LEA        DX, pseudo_overlay_name
  273.     PUSH        DS
  274.     POP        ES
  275.     LEA        BX, parm_block
  276.     INT        21h
  277.     JC        emm_err_exit
  278.  
  279.     ;---------------------------------------------------------------------;
  280.     ;   Transfer control to the loaded pseudo-overlays initialization     ;
  281.     ;   code.                                                             ;
  282.     ;---------------------------------------------------------------------;
  283.     PUSH        DS                    
  284.     PUSH        ES                    
  285.     CALL        DWORD PTR com_file_entry_point
  286.     POP        ES
  287.     POP        DS
  288.     OR        AH, AH
  289.     JZ        call_overlay_procedures
  290.     JMP        emm_err_exit
  291.  
  292. call_overlay_procedures:
  293.     ;---------------------------------------------------------------------;
  294.     ;   As an example of passing control to a procedure existing in       ;
  295.     ;   expanded memory, each procedure contained in the overlay will be  ;
  296.     ;   called in sequence.  Obviously, a single procedure could be       ;
  297.     ;   called just as easily.                                            ;
  298.     ;---------------------------------------------------------------------;
  299.     MOV        ES, exp_mem_segment            
  300.     MOV        BX, 0                    
  301.     MOV        DI, 0                    
  302.     MOV        CX, ES:[BX].proc_entry_count        
  303.     JCXZ        deallocate_exp_memory            
  304.                             
  305. pseudo_overlay_call_loop:
  306.     ;---------------------------------------------------------------------;
  307.     ;   Indicate that code in expanded memory is being called.            ;
  308.     ;---------------------------------------------------------------------;
  309.     DISPLAY        calling_overlay_msg
  310.  
  311.     ;---------------------------------------------------------------------;
  312.     ;   Call the procedures loaded in the overlay.                        ;
  313.     ;---------------------------------------------------------------------;
  314.     PUSH        BX
  315.     PUSH        CX
  316.     PUSH        DI
  317.     PUSH        ES
  318.     PUSH        DS
  319.  
  320.     LDS        AX, ES:[BX+DI].proc_entry_ptr
  321.     MOV        WORD PTR CS:temp_proc_entry_ptr[0], AX
  322.     MOV        WORD PTR CS:temp_proc_entry_ptr[2], DS
  323.  
  324.     ;---------------------------------------------------------------------;
  325.     ;   Pass 2 numbers to the procedures.                                 ;
  326.     ;---------------------------------------------------------------------;
  327.     MOV        AX, 123                    
  328.     MOV        DX, 23
  329.  
  330.     ;---------------------------------------------------------------------;
  331.     ;   Set up pseudo-overlays segment environment.  Call each procedure. ;
  332.     ;---------------------------------------------------------------------;
  333.     MOV        DS, ES:[BX].proc_data_segment        
  334.     MOV        ES, ES:[BX].proc_extra_segment        
  335.     CALL        DWORD PTR CS:temp_proc_entry_ptr    
  336.  
  337.     POP        DS
  338.     POP        ES
  339.     POP        DI
  340.     POP        CX
  341.     POP        BX
  342.  
  343.     ;---------------------------------------------------------------------;
  344.     ;   Adjust index to the next procedure (4 bytes long) pointer & loop  ;
  345.     ;   till all have been called.                                        ;
  346.     ;---------------------------------------------------------------------;
  347.     ADD        DI, 4                    
  348.     LOOP        pseudo_overlay_call_loop        
  349.  
  350. deallocate_exp_memory:
  351.     ;---------------------------------------------------------------------;
  352.     ;   Dellocating expanded memory for overlay.                          ;
  353.     ;---------------------------------------------------------------------;
  354.     DISPLAY        dealloc_exp_mem_msg
  355.  
  356.     ;---------------------------------------------------------------------;
  357.     ;   Return the allocated pages to the expanded memory manager.        ;
  358.     ;---------------------------------------------------------------------;
  359.     MOV        AH, 45h                    
  360.     MOV        DX, EMM_handle                
  361.     INT        67h                    
  362.     OR        AH, AH
  363.     JNZ        emm_err_exit
  364.  
  365. exit:
  366.     ;---------------------------------------------------------------------;
  367.     ;   Return a normal exit code.                                        ;
  368.     ;---------------------------------------------------------------------;
  369.     MOV        AH, 4Ch                    
  370.     MOV        AL, 0
  371.     INT        21h
  372.  
  373. emm_err_exit:
  374.     ;---------------------------------------------------------------------;
  375.     ;   Display the fact that an EMM error occurred & exit.               ;
  376.     ;---------------------------------------------------------------------;
  377.     DISPLAY        emm_err_msg                
  378.     MOV        AH, 4Ch                    
  379.     MOV        AL, 1
  380.     INT        21h
  381.  
  382.     ;---------------------------------------------------------------------;
  383.     ;   CS relative far pointer used for transfer to the procedures in    ;
  384.     ;   the pseudo_overlay.                                               ;
  385.     ;---------------------------------------------------------------------;
  386.     temp_proc_entry_ptr    DD    ?        
  387.                             
  388. main    ENDP                        
  389.  
  390.  
  391. PAGE
  392. ;-----------------------------------------------------------------------------;
  393. ;   The following procedure tests for the presence of the EMM in the system.  ;
  394. ;   It returns the CARRY FLAG SET if the EMM is present.  It returns the      ;
  395. ;   CARRY FLAG CLEAR if the EMM is not present.                               ;
  396. ;-----------------------------------------------------------------------------;
  397.  
  398. test_for_EMM PROC NEAR
  399.  
  400.     ;---------------------------------------------------------------------;
  401.     ;   Issue "get interrupt vector" DOS call.                            ;
  402.     ;---------------------------------------------------------------------;
  403.     MOV        AX, 3567h                
  404.     INT        21h
  405.  
  406.     ;---------------------------------------------------------------------;
  407.     ;   Use the SEGMENT in ES returned by DOS, place the "device name     ;
  408.     ;   field" OFFSET in DI.                                              ;
  409.     ;---------------------------------------------------------------------;
  410.     MOV        DI, 000Ah                
  411.     
  412.     ;---------------------------------------------------------------------;
  413.     ;   Place the OFFSET of the EMM device name string in SI, the SEGMENT ;
  414.     ;   is already in DS.                                                 ;
  415.     ;---------------------------------------------------------------------;
  416.     LEA        SI, EMM_device_name            
  417.                             
  418.     ;---------------------------------------------------------------------;
  419.     ;   Compare the name strings.  Return the status of the compare in    ;
  420.     ;   the ZERO flag.                                                    ;
  421.     ;---------------------------------------------------------------------;
  422.     MOV        CX, (SIZE EMM_device_name)        
  423.     CLD                        
  424.     REPE        CMPSB                    
  425.     RET
  426.  
  427. test_for_EMM ENDP
  428.  
  429.  
  430. CODE    ENDS
  431.  
  432.  
  433. PAGE
  434. ;-----------------------------------------------------------------------------;
  435. ;       S T A C K   S E G M E N T    F O R   T H E   K E R N A L              ;
  436. ;             A N D   T H E   P S E U D O - O V E R L A Y                     ;
  437. ;-----------------------------------------------------------------------------;
  438.  
  439. STACK    SEGMENT PARA STACK 'STACK'
  440.     local_stack    DW 256 DUP ('^^')
  441. STACK    ENDS
  442.  
  443. END    main
  444.