home *** CD-ROM | disk | FTP | other *** search
/ High Voltage Shareware / high1.zip / high1 / DIR2 / 4DEMS.ZIP / EMS.ASM next >
Assembly Source File  |  1993-11-13  |  16KB  |  548 lines

  1. COMMENT ~
  2. /*-------------------------------------------------------------------------+
  3. | Module: EMS.ASM                                                          |
  4. | Project: TOOLS                                                           |
  5. | Author: Paul A. Penrose                                                  |
  6. |         (c) 1992, 4D Interactive Systems, Inc.  All rights reserved.     |
  7. | Start Date: 01 Nov 92                                                    |
  8. | Last Revised: 29 Nov 92                                                  |
  9. | Purpose:                                                                 |
  10. |   This module contains the EMS support code.  The functions provided are |
  11. |   C callable and provide complete linkage to the EMS services supported. |
  12. +-------------------------------------------------------------------------*/ ~
  13.  
  14. IDEAL
  15.  
  16. MODEL HUGE,C
  17.  
  18. P286N
  19.  
  20. DATASEG
  21. ;
  22. ; Define the equates here
  23. ;
  24.  
  25. ;
  26. ; Define structures here
  27. ;
  28. STRUC physical_map
  29.   segment_sel   DW ?
  30.   page_num      DW ?
  31. ENDS
  32.  
  33. STRUC handle_size_map
  34.   handle        DW ?
  35.   num_pages     DW ?
  36. ENDS
  37.  
  38. STRUC handle_name_map
  39.   handle        DW ?
  40.   handle_name   DB 8 DUP(?)
  41. ENDS
  42.  
  43. STRUC handle_directory
  44.   handle        DW ?
  45.   num_pages     DW ?
  46.   handle_name   DB 9 DUP(?)
  47. ENDS
  48.  
  49. ;
  50. ; Declare module level data here
  51. ;
  52. ALIGN 2
  53. ems_pageframe           DW  0
  54. ems_errnum              DB  0
  55. ems_function            DB  0
  56. ems_version             DB  0
  57. ASCII_device_name       DB  'EMMXXXX0', 0
  58. map_buffer              DB  2550 DUP(0)
  59. name_buffer             DB  8 DUP(0)
  60. temp                    DW  ?
  61. copyright               DB  'EMS functions (c) 1992, 4D Interactive Systems, Inc. '
  62.                         DB  'All rights reserved'
  63.  
  64. PUBLIC  ems_errnum, ems_function, ems_version, ems_pageframe
  65.  
  66. CODESEG
  67.  
  68. ;
  69. ; This function initializes the EMS package.  TRUE is returned if the
  70. ; initialization is sucessfull, otherwise FALSE is returned.
  71. ;
  72. PROC    ems_init
  73. ;
  74. ; First check to see if there is an EMS driver loaded
  75. ;       
  76.         push ds                 ;Perform entry setup
  77.         mov  ax,seg ems_function
  78.         mov  ds,ax
  79.         mov  [ems_function],0
  80.         mov  ax,3D00H           ;Open file, read only
  81.         mov  dx,offset ASCII_device_name
  82.         int  21H
  83.         jc   ei_no_driver       ;If not found, report no driver
  84.         mov  bx,ax
  85.         push bx
  86.         mov  [ems_function],1
  87.         mov  ax,4400H           ;Get device info
  88.         int  21H
  89.         pop  bx
  90.         jc   ei_no_driver2
  91.         test dx,0080H           ;Is it a device?
  92.         jz   ei_no_driver2
  93.         push bx
  94.         mov  ax,4407H           ;Is the device ready?
  95.         int  21H
  96.         pop  bx
  97.         or   al,al
  98.         jz   ei_no_driver2
  99.         mov  ax,3E00H           ;Close the driver
  100.         int  21H
  101. ;
  102. ; Get the EMS version and store it for later reference
  103. ;
  104.         mov  ah,46H
  105.         mov  [ems_function],ah
  106.         int  67H
  107.         mov  [ems_errnum],ah
  108.         mov  [ems_version],al
  109.         or   ah,ah
  110.         jnz  ei_error
  111. ;
  112. ; Next get the pageframe and store it for later reference
  113. ;
  114.         mov  ah,41H
  115.         mov  [ems_function],ah
  116.         int  67H
  117.         mov  [ems_errnum],ah
  118.         mov  [ems_pageframe],bx
  119.         or   ah,ah
  120.         jnz  ei_error
  121.         mov  ax,1               ;Return TRUE
  122.         jmp  ei_exit
  123. ei_no_driver2:
  124.         mov  ax,3E00H           ;Close the driver
  125.         int  21H
  126. ei_no_driver:
  127. ei_error:
  128.         xor  ax,ax              ;Return FALSE
  129. ei_exit:
  130.         pop  ds
  131.         ret
  132. ENDP
  133. PUBLIC  ems_init
  134.  
  135. ;
  136. ; This function returns the number of free (available) EMS pages
  137. ;
  138. PROC    ems_num_free_pages
  139.         ARG  true_size:WORD
  140.  
  141.         push ds                 ;Perform entry setup
  142.         mov  ax,seg ems_function
  143.         mov  ds,ax
  144.         test [true_size],0FFFFH         ;Report true size?
  145.         jz   nfp_001
  146.         mov  bx,4444H                   ;Put signature "DDDD" in BX:DX
  147.         mov  dx,4444H
  148. nfp_001:
  149.         mov  ah,42H
  150.         mov  [ems_function],ah
  151.         int  67H
  152.         mov  [ems_errnum],ah
  153.         mov  ax,bx
  154.         pop  ds
  155.         ret
  156. ENDP
  157. PUBLIC  ems_num_free_pages
  158.  
  159. ;
  160. ; This function is used to allocate a number of EMS pages.  It returns a
  161. ; handle that is used to identify these pages to other EMS functions.  If
  162. ; a handle of -1 is returned, an error occured.  An optional name of up to
  163. ; 8 characters can be passed that is used to name the handle.  This name is
  164. ; ignored for EMS driver versions less than 4.0.
  165. ;
  166. PROC    ems_alloc
  167.         ARG num_pages:WORD
  168.         ARG handle_name:DWORD
  169.  
  170.         push ds                 ;Perform entry setup
  171.         mov  ax,seg ems_function
  172.         mov  ds,ax
  173.         push si
  174.         push di
  175.         mov  ah,43H
  176.         mov  [ems_function],ah
  177.         mov  bx,[num_pages]
  178.         int  67H
  179.         mov  [ems_errnum],ah
  180.         or   ah,ah
  181.         jz   ea_good
  182.         mov  dx,0FFFFH                  ;Return -1 if error
  183. ea_good:
  184.         push dx
  185.         cmp  [ems_version],40H          ;Check if we can name it
  186.         jb   ea_exit                    ;  exit if version < 4.0
  187.         les  si,[handle_name]           ;Check the name ptr (NULL = none)
  188.         mov  ax,es
  189.         or   ax,si
  190.         jz   ea_exit
  191.         mov  ax,es                      ;Zero out name_buffer
  192.         push ds                         ;  first swap DS and ES
  193.         pop  es
  194.         mov  ds,ax
  195.         xor  ax,ax                      ;  now set up the loop
  196.         mov  cx,4
  197.         mov  di,offset name_buffer      ;  and zero out the buffer
  198. ea_loop1:
  199.         stosw
  200.         loop ea_loop1
  201.         mov  di,offset name_buffer      ;Copy the name into the buffer
  202.         mov  cx,8                       ;  but only the first 8 chars
  203. ea_loop2:
  204.         lodsb
  205.         or   al,al
  206.         jz   ea_endcopy                 ;Exit if end of string
  207.         stosb
  208.         loop ea_loop2
  209. ea_endcopy:
  210.         push es                         ;Restore DS
  211.         pop  ds
  212.         mov  ax,5301H                   ;Set name
  213.         pop  dx                         ;Get handle
  214.         push dx                         ;  and save it again
  215.         mov  si,offset name_buffer
  216.         mov  [ems_function],ah
  217.         int  67H
  218.         mov  [ems_errnum],ah
  219. ea_exit:
  220.         pop  ax                         ;Recover handle
  221.         pop  di
  222.         pop  si
  223.         pop  ds
  224.         ret
  225. ENDP
  226. PUBLIC  ems_alloc
  227.  
  228. ;
  229. ; This function is used to free up EMS pages previously allocated using the
  230. ; ems_alloc function.
  231. ;
  232. PROC    ems_free
  233.         ARG handle:WORD
  234.  
  235.         push ds                 ;Perform entry setup
  236.         mov  ax,seg ems_function
  237.         mov  ds,ax
  238.         mov  ah,45H
  239.         mov  [ems_function],ah
  240.         mov  dx,[handle]
  241.         int  67H
  242.         mov  [ems_errnum],ah
  243.         mov  al,ah
  244.         mov  al,0
  245.         pop  ds
  246.         ret
  247. ENDP
  248. PUBLIC  ems_free
  249.  
  250. ;
  251. ; This function is used to map a logical page that was previously allocated
  252. ; using the ems_alloc function to a physical page.  A non-zero return value
  253. ; indicates an error occured.
  254. ;
  255. PROC    ems_map_page
  256.         ARG handle:WORD
  257.         ARG logical_page:WORD
  258.         ARG physical_page:WORD
  259.  
  260.         push ds                 ;Perform entry setup
  261.         mov  ax,seg ems_function
  262.         mov  ds,ax
  263.         mov  bx,[logical_page]
  264.         mov  ax,[physical_page]
  265.         mov  dx,[handle]
  266.         mov  ah,44H
  267.         mov  [ems_function],ah
  268.         int  67H
  269.         mov  [ems_errnum],ah
  270.         mov  al,ah
  271.         xor  ah,ah
  272.         pop  ds
  273.         ret
  274. ENDP
  275. PUBLIC  ems_map_page
  276.  
  277. ;
  278. ; This function is used to unmap logical page that is currently mapped to
  279. ; a physical page.  A non-zero return value indicates an error occured.
  280. ;
  281. PROC    ems_unmap_page
  282.         ARG handle:WORD
  283.         ARG physical_page:WORD
  284.  
  285.         push ds                 ;Perform entry setup
  286.         mov  ax,seg ems_function
  287.         mov  ds,ax
  288.         mov  ax,[physical_page]
  289.         mov  dx,[handle]
  290.         mov  bx,0FFFFH
  291.         mov  ah,44H
  292.         mov  [ems_function],ah
  293.         int  67H
  294.         mov  [ems_errnum],ah
  295.         mov  al,ah
  296.         xor  ah,ah
  297.         pop  ds
  298.         ret
  299. ENDP
  300. PUBLIC  ems_unmap_page
  301.  
  302. ;
  303. ; This function returns the number of physical pages available in the EMS
  304. ; page frame.
  305. ;
  306. PROC    ems_num_physical_pages
  307.         push ds                 ;Perform entry setup
  308.         mov  ax,seg ems_function
  309.         mov  ds,ax
  310.         cmp  [ems_version],40H          ;Is it ver 4.0 or greater?
  311.         jae  enpp_001
  312.         mov  ax,4                       ;Return 4 pages if ver < 4.0
  313.         pop  ds
  314.         ret
  315. enpp_001:
  316.         push si
  317.         push di
  318.         mov  ax,seg map_buffer          ;Get a map of all mappable physical
  319.         mov  es,ax                      ;  pages in the system
  320.         mov  di,offset map_buffer
  321.         mov  ax,5800H
  322.         mov  [ems_function],ah
  323.         int  67H
  324.         or   ah,ah
  325.         jz   enpp_002
  326.         mov  [ems_errnum],ah            ;Return error
  327.         xor  ax,ax
  328.         pop  ds
  329.         ret
  330. enpp_002:
  331.         mov  si,offset map_buffer       ;Search through the map
  332.         mov  dx,0                       ;highest page found
  333. enpp_003:
  334.         mov  ax,[(physical_map PTR si).page_num]
  335.         cmp  ax,3                       ;Skip this one if it's > 3
  336.         ja   enpp_004
  337.         cmp  ax,dx                      ;Skip if < highest
  338.         jb   enpp_004
  339.         mov  dx,ax                      ;This is the highest < 4
  340. enpp_004:
  341.         add  si,4
  342.         loop enpp_003
  343.         mov  ax,dx                      ;Get the highest page < 4
  344.         inc  ax                         ;Return number of pages
  345.         pop  di
  346.         pop  si
  347.         pop  ds
  348.         ret
  349. ENDP
  350. PUBLIC  ems_num_physical_pages
  351.  
  352. ;
  353. ; This function returns the number of open EMS handles
  354. ;
  355. PROC    ems_num_open_handles
  356.         push ds                 ;Perform entry setup
  357.         mov  ax,seg ems_function
  358.         mov  ds,ax
  359.         mov  ah,4BH
  360.         mov  [ems_function],ah
  361.         int  67H
  362.         mov  [ems_errnum],ah            ;Return error
  363.         mov  ax,bx
  364.         pop  ds
  365.         ret
  366. ENDP
  367. PUBLIC  ems_num_open_handles
  368.  
  369. ;
  370. ; This function will fill in an EMS directory map structure with the current
  371. ; status of all open EMS handles.  Returns 0 if no error, else error code.
  372. ;
  373. PROC    ems_get_handle_directory
  374.         ARG  handle_dir:DWORD
  375.  
  376.         push ds                 ;Perform entry setup
  377.         mov  ax,seg ems_function
  378.         mov  ds,ax
  379.         push si
  380.         push di
  381.         push ds                         ;Get map showing number of pages for
  382.         pop  es                         ;  each handle
  383.         mov  di,offset map_buffer
  384.         mov  ah,4DH
  385.         mov  [ems_function],ah
  386.         int  67H
  387.         mov  [ems_errnum],ah            ;Return error
  388.         or   ah,ah
  389.         jnz  eghd_exit
  390.         mov  cx,bx
  391.         mov  si,offset map_buffer       ;Search through the returned data and
  392.         les  di,[handle_dir]            ;  post it to the hande dir
  393. eghd_loop1:
  394.         mov  ax,[(handle_size_map PTR si).handle]
  395.         mov  [es:(handle_directory PTR di).handle],ax
  396.         mov  ax,[(handle_size_map PTR si).num_pages]
  397.         mov  [es:(handle_directory PTR di).num_pages],ax
  398.         mov  [es:(handle_directory PTR di).handle_name],0
  399.         add  di,13
  400.         add  si,4
  401.         loop eghd_loop1
  402.  
  403.         cmp  [ems_version],40H          ;Exit if ems_version < 4.0
  404.         jb   eghd_exit
  405.         push ds                         ;Get map of name for each handle
  406.         pop  es
  407.         mov  di,offset map_buffer
  408.         mov  ax,5400H
  409.         mov  [ems_function],ah
  410.         int  67H
  411.         mov  [ems_errnum],ah            ;Return error
  412.         or   ah,ah
  413.         jnz  eghd_exit
  414.         mov  cx,ax
  415.         mov  [temp],cx
  416.         mov  si,offset map_buffer       ;Search through the returned data and
  417.         les  di,[handle_dir]            ;  post it to the handle dir
  418. eghd_loop2:
  419.         mov  ax,[(handle_name_map PTR si).handle]
  420.         push di                         ;Find the same handle in the dir
  421.         push cx                         ;  (don't assume that the handles are
  422.         mov  cx,[temp]                  ;   in the same order as the previous
  423. eghd_loop3:                             ;   call)
  424.         cmp  ax,[es:(handle_directory PTR di).handle]
  425.         je   eghd_handle_found
  426.         add  di,13
  427.         loop eghd_loop3
  428.         jmp  eghd_next_handle
  429. eghd_handle_found:
  430.         push si                         ;Copy the name into the directory
  431.         add  si,2                       ;Point to name field
  432.         add  di,4                       ;ditto
  433.         mov  cx,4
  434.         rep movsw                       ;copy the name
  435.         xor  al,al
  436.         stosb                           ;make sure string is terminated
  437.         pop  si
  438. eghd_next_handle:
  439.         pop  cx                         ;Process the next entry
  440.         pop  di
  441.         add  si,10
  442.         loop eghd_loop2
  443.         xor  ah,ah
  444. eghd_exit:
  445.         xor  al,al
  446.         pop  di
  447.         pop  si
  448.         pop  ds
  449.         ret
  450. ENDP
  451. PUBLIC  ems_get_handle_directory
  452.  
  453. ;
  454. ; This function will find the handle for any named EMS memory block and return
  455. ; it to the caller.  If the name can't be found, 0xFFFF is returned.
  456. ;
  457. PROC    ems_find_handle
  458.         ARG  handle_name:DWORD
  459.  
  460.         push ds                 ;Perform entry setup
  461.         mov  ax,seg ems_function
  462.         mov  ds,ax
  463.         push si
  464.         push di
  465.         les  si,[handle_name]           ;Check the name ptr (NULL = none)
  466.         mov  ax,es
  467.         or   ax,si
  468.         jz   efh_exit
  469.         mov  ax,es                      ;Zero out name_buffer
  470.         push ds                         ;  first swap DS and ES
  471.         pop  es
  472.         mov  ds,ax
  473.         xor  ax,ax                      ;  now set up the loop
  474.         mov  cx,4
  475.         mov  di,offset name_buffer      ;  and zero out the buffer
  476. efh_loop1:
  477.         stosw
  478.         loop efh_loop1
  479.         mov  di,offset name_buffer      ;Copy the name into the buffer
  480.         mov  cx,8                       ;  but only the first 8 chars
  481. efh_loop2:
  482.         lodsb
  483.         or   al,al
  484.         jz   efh_endcopy                 ;Exit if end of string
  485.         stosb
  486.         loop efh_loop2
  487. efh_endcopy:
  488.         push es                         ;Restore DS
  489.         pop  ds
  490.         mov  ax,5401H                   ;Find Name
  491.         mov  si,offset name_buffer
  492.         mov  [ems_function],ah
  493.         int  67H
  494.         mov  [ems_errnum],ah
  495.         or   ah,ah
  496.         jz   efh_exit
  497.         mov  dx,0FFFFH
  498. efh_exit:
  499.         mov  ax,dx                      ;Return handle
  500.         pop  di
  501.         pop  si
  502.         pop  ds
  503.         ret
  504. ENDP
  505. PUBLIC  ems_find_handle
  506.  
  507. ;
  508. ; This function will save the current EMS Page Frame mapping context.         
  509. ;
  510. PROC    ems_save_mapping_context
  511.         ARG  handle:WORD
  512.  
  513.         push ds                 ;Perform entry setup
  514.         mov  ax,seg ems_function
  515.         mov  ds,ax
  516.         mov  ah,47H
  517.         mov  [ems_function],ah
  518.         mov  dx,[handle]
  519.         int  67H
  520.         mov  [ems_errnum],ah            ;Return error
  521.         xor  al,al
  522.         pop  ds
  523.         ret
  524. ENDP
  525. PUBLIC  ems_save_mapping_context
  526.  
  527. ;
  528. ; This function will restore the current EMS Page Frame mapping context.         
  529. ;
  530. PROC    ems_restore_mapping_context
  531.         ARG  handle:WORD
  532.  
  533.         push ds                 ;Perform entry setup
  534.         mov  ax,seg ems_function
  535.         mov  ds,ax
  536.         mov  ah,48H
  537.         mov  [ems_function],ah
  538.         mov  dx,[handle]
  539.         int  67H
  540.         mov  [ems_errnum],ah            ;Return error
  541.         xor  al,al
  542.         pop  ds
  543.         ret
  544. ENDP
  545. PUBLIC  ems_restore_mapping_context
  546.  
  547. END
  548.