home *** CD-ROM | disk | FTP | other *** search
/ Microsoft Programmer's Library 1.3 / Microsoft-Programers-Library-v1.3.iso / sampcode / msj / msjv4_5 / ems / emstools.asm next >
Encoding:
Assembly Source File  |  1989-05-08  |  23.6 KB  |  794 lines

  1. ;=============================================================================
  2. ;                       Assembly language EMS routines
  3. ;                         written by Douglas Boling
  4. ;                       (c) 1989 Microsoft Corporation
  5. ;=============================================================================
  6.  
  7.          .MODEL    small
  8.  
  9.         .DATA
  10.  
  11. ems_header      db      "EMMXXXX0",0            ;ASCIIZ EMS driver name
  12. fun25_array    dw    96 dup (0)        ;Array for physical page data
  13. fun25_array_end    =    $
  14.  
  15. ems32up_version    db    0              ;Version number for dispatcher
  16. ems32up_calltbl    dw    offset EMSMapMultiple
  17.         dw    offset EMSMapandJump
  18.         dw    offset EMSMapandCall
  19.  
  20.         .CODE
  21.  
  22.         PUBLIC    GetEMSMem
  23.         PUBLIC    SaveEMSMem
  24.         PUBLIC    RestoreEMSMem
  25.         PUBLIC    FreeEMSMem
  26.         PUBLIC    CheckAlias
  27.         PUBLIC    MapbyName
  28.         PUBLIC    EMS32Upgrade
  29.  
  30. ;=============================================================================
  31. ;GetEMSMem reserves the amount of Expanded memory requested in BX.
  32. ; Entry: BX - amount of memory to reserve
  33. ;        SI - Pointer to name to assign to handle in ASCIIZ format.
  34. ;             Set SI = -1 for no name.
  35. ; Exit:  AL - EMM Version.
  36. ;        BX - segment of page frame.
  37. ;        CX - Size of page frame.
  38. ;        DX - EMS handle.
  39. ;=============================================================================
  40. GetEMSMem       proc
  41.         push    bp
  42.         mov    bp,sp
  43.         push    ax
  44.         push    bx
  45.         push    cx
  46.         push    dx
  47.         push    di
  48.         push    si
  49.         push    es
  50. ;-----------------------------------------------------------------------------
  51. ;See if EMS driver installed.
  52. ;-----------------------------------------------------------------------------
  53.         call    FindEMS            ;See if EMM is loaded
  54.         or    ah,ah                   ;Check for error
  55.         jne     getp_error              ; RC <> 0, error
  56. ;-----------------------------------------------------------------------------
  57. ;Reserve pages.
  58. ;-----------------------------------------------------------------------------
  59.         mov    bx,[bp-4]        ;Get number of pages to res
  60.         mov    ah,43h            ;EMS Allocate pages function
  61.         int    67h            ;Call EMS Driver
  62.         or    ah,ah            ;Check for error
  63.         jne     getp_error        ;If error, exit.
  64.         mov    [bp-8],dx               ;Save handle.
  65. ;-----------------------------------------------------------------------------
  66. ;Get version.
  67. ;-----------------------------------------------------------------------------
  68.         mov     ah,46h            ;Get Expanded Memory version
  69.         int     67h
  70.         or      ah,ah
  71.         jne     getp_error
  72.         mov    [bp-2],al        ;Save version
  73.         mov    dl,al
  74. ;-----------------------------------------------------------------------------
  75. ;See how many physical pages and the number of pages in the page frame.
  76. ;-----------------------------------------------------------------------------
  77.         mov    cx,4            ;Assume EMM ver 3.2, 4 pages
  78.         mov    bx,cx            ;Save number of pages in frame
  79.         cmp    dl,40h            ;Check for version 4.0
  80.         jb    getp_continue             ;If before 4.0, use 4 pages
  81.         mov    ax,5801h        ;Get number of entries in the
  82.         int    67h            ;  map array.
  83.         or    ah,ah            ;Check for error
  84.         jne    getp_error
  85.         mov    ax,cx            ;Copy number of entries
  86.         sal    ax,1                    ;Mult number of entries by 4
  87.         sal    ax,1
  88.         cmp    ax,offset fun25_array_end - offset fun25_array
  89.         jb    getp_2
  90.         mov    ah,0f2h            ;Load array too large RC
  91.         jmp     getp_exit
  92. getp_2:
  93.                 mov    bx,cx            ;Copy number of physical pages
  94.         mov    ax,ds            ;Set ES = DS
  95.         mov    es,ax
  96.         mov    di,offset fun25_array
  97.         mov    ax,5800h        ;Get mappable page array
  98.         int    67h            ;Call driver
  99.         or    ah,ah
  100.         jne    getp_error
  101.         xor    ax,ax
  102. getp_loop2:
  103.         cmp    ax,[di+2]        ;Search list for physical page
  104.         je    getp_3                  ;  zero. That is the start of
  105.         add    di,4                    ;  the page frame.
  106.         loop    getp_loop2
  107.         mov    ah,0f3h            ;Page frame not found in list.
  108. getp_error:
  109.         jmp    getp_exit
  110. getp_3:
  111.         xor    bx,bx            ;Zero consecutive page count
  112. getp_loop3:
  113.         inc    bx            ;Count the number of
  114.         mov    dx,[di]            ;  consecutive segments.
  115.         add    dx,1024            ;Add num of paragraphs per seg
  116.         cmp    dx,[di+4]        ;Compare with next segment
  117.         jne    getp_continue        ;If not consecutive, exit
  118.         add    di,4            ;Point to next entry
  119.         loop    getp_loop3
  120. getp_continue:
  121.         mov     [bp-6],bx        ;Put page frame size into
  122.         mov    cx,[bp-4]        ;  stack and get num of pages
  123. ;-----------------------------------------------------------------------------
  124. ;Map pages into page frame.
  125. ;-----------------------------------------------------------------------------
  126.         cmp    cx,bx            ;See if number of pages larger
  127.         jb    getp_4            ;  that the size of the frame.
  128.         mov    cx,bx            ;Use the page frame size.
  129. getp_4:
  130.         xor    bx,bx            ;Start with logical page 0
  131.         mov    dx,[bp-8]        ;Get back handle
  132. getp_loop4:
  133.         mov     al,bl            ;  at physical page 0
  134.         mov    ah,44h            ;EMS Map Page function
  135.         int     67h            ;Call EMS Driver
  136.         or    ah,ah            ;Check for error
  137.         jne     getp_exit        ;If error, exit.
  138.         inc    bx            ;Point to next logical page
  139.         loop    getp_loop4
  140. ;-----------------------------------------------------------------------------
  141. ;Get page frame segment.
  142. ;-----------------------------------------------------------------------------
  143.         mov    ah,41h            ;EMS Get page frame segment
  144.         int    67h            ;Call EMS Driver
  145.         or    ah,ah            ;Check for error
  146.         jne     getp_exit        ;If error, exit.
  147.         mov    [bp-4],bx               ;Save page frame segment.
  148. ;-----------------------------------------------------------------------------
  149. ;Set the handle name.
  150. ;-----------------------------------------------------------------------------
  151.         xor    ax,ax            ;Zero return code.
  152.         mov    si,[bp-12]        ;Get back name pointer
  153.         cmp    si,-1             ;if -1, no name
  154.         je    getp_exit
  155.         mov    dx,[bp-8]        ;Get handle
  156.         mov    ax,5301h        ;EMS Set Handle Name.
  157.         int    67h            ;Call EMS Driver
  158.         or    ah,ah            ;Check for error
  159.         jne     getp_exit        ;If error, exit.
  160. getp_exit:
  161.         mov    [bp-1],ah        ;Save return code on stack
  162.         pop    es
  163.         pop    si
  164.         pop    di
  165.         pop    dx
  166.         pop    cx
  167.         pop    bx
  168.         pop    ax
  169.         pop    bp
  170.         ret
  171. GetEMSMem       endp
  172.  
  173. ;=============================================================================
  174. ;SaveEMSMem Saves the context of EMS driver.
  175. ; Entry:    CX - Size of save area in bytes.
  176. ;        ES:DI - Pointer to save area
  177. ; Exit:     AH - Return code
  178. ;           DX - Index, Used to identify saved state.
  179. ;=============================================================================
  180. SaveEMSMem    proc
  181.         push    bx
  182.         push    cx
  183.         push    di
  184.         mov    ax,4e03h        ;Get save area size
  185.         int    67h
  186.         xor    ah,ah            ;Clear top byte of save size
  187.         add    ax,4
  188.         mov    bx,di            ;Copy buffer pointer
  189.         cmp    word ptr es:[di],4244h    ;Check for initialized area
  190.         je    save_1
  191.         mov    es:[di],4244h           ;Load signature
  192.         xor    dx,dx
  193.         mov    es:[di+4],dx            ;Init first index
  194.         dec    dx
  195.         mov    es:[di+2],dx            ;Init queue end pointer
  196. save_1:
  197. ;-----------------------------------------------------------------------------
  198. ;Find the first free area in the save buffer.
  199. ;-----------------------------------------------------------------------------
  200.         inc    di
  201.         inc    di
  202.         add    cx,bx            ;Add base address to size but
  203.         sub    cx,ax                   ;  subtract entry size.
  204.         xor    dx,dx
  205. save_2:
  206.         cmp    dx,es:[di+2]        ;Find max value of index
  207.         jae    save_3                  ;  in the queue.
  208.         mov    dx,es:[di+2]
  209. save_3:
  210.         cmp    word ptr es:[di],-1     ;If = -1 then this is the
  211.         je    save_4                  ;  last entry.
  212.         add    di,es:[di]        ;Point to next entry
  213.         jc    save_areafull        ;Check for end of segment and
  214.         cmp    di,cx            ;  end of buffer.
  215.         ja    save_areafull
  216.         jmp    short save_2
  217. save_4:
  218.         add    di,4            ;Move past queue overhead
  219.         inc    dx            ;Create new index.
  220.         push    ax
  221.         mov    ax,4e00h        ;Save page map
  222.         int    67h
  223.         or    ah,ah
  224.         pop    ax
  225.         jne    save_exit
  226.         mov    es:[di-4],ax        ;Update queue pointers
  227.         mov    es:[di-2],dx
  228.         add    di,ax
  229.         sub    di,4
  230.         mov    word ptr es:[di],-1
  231. save_exit:
  232.         pop    di
  233.         pop    cx
  234.         pop    bx
  235.         ret
  236. save_areafull:
  237.         mov    ah,8ch            ;Save area full
  238.         jmp    short save_exit
  239. SaveEMSMem    endp
  240.  
  241. ;=============================================================================
  242. ;RestoreEMSMem Restore the context of EMS driver.
  243. ; Entry:    DX - Index, value returned by SaveEMSMem when state saved
  244. ;        DS:SI - Pointer to save area
  245. ; Exit:     AH - Return code
  246. ;=============================================================================
  247. RestoreEMSMem    proc
  248.         pushf
  249.         push    cx
  250.         push    di
  251.         push    si
  252.         mov    ax,[si]            ;Check for initialized area
  253.         cmp    ax,4244h
  254.         jne    restore_bad
  255.         inc    si            ;Point to first entry
  256.         inc    si
  257. restore_1:
  258.         cmp    [si+2],dx               ;Find index value
  259.         je    restore_2
  260.         cmp    word ptr [si],-1    ;See if at end of queue
  261.         je    restore_bad
  262.         add    si,[si]
  263.         jc    restore_bad        ;If overflow segment, error
  264.         jmp    short restore_1
  265. restore_2:
  266.         mov    di,si            ;Copy entry
  267.         add    si,4            ;Point to save array
  268.         mov    ax,4e01h        ;Restore page map
  269.         int    67h
  270.         or    ah,ah
  271.         jne    restore_exit
  272.         sub    si,4
  273.         add    si,[di]
  274. restore_3:
  275.         cmp    word ptr [si],-1
  276.         je    restore_4
  277.         mov    cx,[di]            ;Load size
  278.         cld
  279.         rep    movsb            ;Copy next entry
  280.         jmp    short restore_3
  281. restore_4:
  282.         mov    word ptr [di],-1
  283. restore_exit:
  284.         pop    si
  285.         pop    di
  286.         pop    cx
  287.         popf
  288.         ret
  289. restore_bad:
  290.         mov    ah,0a3h
  291.         jmp    short restore_exit
  292. RestoreEMSMem    endp
  293.  
  294. ;=============================================================================
  295. ;FreeEMSMem Deallocates EMS memory
  296. ; Entry:   DX - handle to deallocate
  297. ;=============================================================================
  298. FreeEMSMem    proc
  299.         mov    ah,45h            ;Deallocate pages
  300.         int    67h
  301.         ret
  302. FreeEMSMem    endp
  303.  
  304. ;=============================================================================
  305. ;CheckAlias Checks for memory aliasing support by EMS driver
  306. ; Exit:   AH - return code
  307. ;         AL - 1 Aliasing not supported, 0 - Aliasing supported.
  308. ;=============================================================================
  309. CheckAlias    proc
  310.         pushf
  311.         push    bx
  312.         push    cx
  313.         push    dx
  314.         push    di
  315.         mov    ah,41h            ;Get page frame segment
  316.         int    67h
  317.         or    ah,ah
  318.         jne    chkalias_exit1
  319.         mov    cx,bx            ;Copy page frame
  320. ;Allocate 1 logical page
  321.         mov    ah,43h            ;EMS Allocate page
  322.         mov    bx,1
  323.         int    67h
  324.         or    ah,ah
  325.         jne    chkalias_exit1
  326. ;Map logical page to physical pages 0 and 1.
  327.         mov    ax,4400h        ;Map to page 0
  328.         mov    bx,0            ;Logical page 0
  329.         int    67h
  330.         or    ah,ah
  331.         jne    chkalias_exit
  332.         mov    ax,4401h        ;Map to page 1
  333.         mov    bx,0            ;Logical page 0
  334.         int    67h
  335.         or    ah,ah
  336.         jne    chkalias_exit
  337. ;Write pattern to physical page 0, then compare to page 1.
  338.         xor     bl,bl             ;Clear alias flag
  339.         push    es
  340.         mov    es,cx
  341.         add    cx,400h
  342.         push    cx
  343.         mov    di,100h            ;Point 256 bytes inside page.
  344.         cld
  345.         mov    al,5ah            ;Write to page 0 then check
  346.         mov    cx,8                    ;  for aliasing by scanning
  347.         rep    stosb                   ;  for the same pattern on
  348.         mov    cx,8                    ;  page 1.
  349.         pop    es
  350.         mov    di,100h
  351.         repe    scasb
  352.         pop    es
  353.         je     chkalias_exit
  354.         inc    bl
  355. chkalias_exit:
  356.         mov    ah,45h            ;Deallocate pages
  357.         int    67h
  358.         mov    al,bl            ;Copy alias flag
  359. chkalias_exit1:
  360.         pop    di
  361.         pop    dx
  362.         pop    cx
  363.         pop    bx
  364.         popf
  365.         ret
  366. chkalias_error:
  367.         mov    ax,8000h        ;Indicate SW error
  368.         jmp    short chkalias_exit1
  369. CheckAlias    endp
  370.  
  371. ;=============================================================================
  372. ;MapbyName Map expanded memory pages by name.
  373. ; Entry:   AL - Physical page
  374. ;          BX - Logical page to map.
  375. ;       DS:SI - Pointer to Handle name in ASCIIZ format
  376. ; Exit:    AH - Return code
  377. ;          DX - EMS Handle
  378. ;=============================================================================
  379. MapbyName    proc
  380.         push    cx
  381.         mov    cx,ax            ;Save physical page number
  382.         mov    ax,5401h        ;EMS find handle function
  383.         int    67h            ;Call EMS driver
  384.         or    ah,ah            ;Check for error
  385.         jne    mbn_exit        ;If error, exit
  386.         mov     al,cl            ;Get back physical page
  387.         mov    ah,44h                  ;EMS Map page function
  388.         int    67h            ;Call EMS driver
  389.         pop    cx
  390. mbn_exit:
  391.         ret
  392. MapbyName    endp
  393.  
  394. ;======================================================================
  395. ; FindEMS determines if the EMM is loaded.
  396. ;======================================================================
  397. FindEMS        proc
  398.         call    check_ems_hdl        ;Check for driver using
  399.         jnc    find_1                ;  open handle technique
  400.         rcl    ah,1                 ;If not enough handles, try
  401.         jc     find_driver_error       ;  interrupt technique.
  402.         call    check_ems_int
  403.         jnc    find_1                ;If manager found, continue
  404. find_driver_error:
  405.         mov     ah,0f1h            ;Set error code.
  406.         jmp    short find_exit
  407. find_1:
  408.         mov     ah,40h            ;Check status
  409.         int     67h
  410. find_exit:
  411.         ret
  412. FindEMS        endp
  413.  
  414. ;======================================================================
  415. ; Test for EMS driver (Open Handle Technique)
  416. ;======================================================================
  417. check_ems_hdl    proc
  418.         mov     dx,offset ems_header
  419.         mov     ax,3d00h        ;Open device read only.
  420.         int    21h
  421.         jnc    cemsh_device_open
  422.         cmp    ah,4            ;If file or path not found,
  423.         jb    cemsh_not_found        ;  no EMS driver.
  424.         mov    ah,01h            ;Too many open handles or
  425.         jmp    short cemsh_error    ;  access denied.
  426. cemsh_device_open:
  427.         mov    bx,ax            ;Copy handle
  428.         mov    ax,4400h        ;Get device information.
  429.         int    21h
  430.         jc    cemsh_not_foundclose
  431.         test    dx,80h            ;Test file/device bit
  432.         je    cemsh_not_foundclose    ;0 = file not device
  433.         mov    ax,4407h        ;Get output status
  434.         int    21h
  435.         jc    cemsh_not_foundclose    ;If error, no device
  436.         cmp    al,0ffh            ;Check for ready status
  437.         jne    cemsh_not_foundclose    ;If not ready, no device
  438.         mov    ah,3eh            ;Close handle
  439.         int    21h            ;BX contains handle
  440.         clc
  441. cemsh_exit:
  442.         ret
  443. cemsh_not_foundclose:
  444.         mov    ah,3eh            ;Close handle
  445.         int    21h            ;BX contains handle
  446. cemsh_not_found:
  447.         mov    ah,81h            ;Not found error code
  448. cemsh_error:
  449.         stc
  450.         jmp     short cemsh_exit
  451. check_ems_hdl    endp
  452.  
  453. ;======================================================================
  454. ; Test for EMS driver (Get Interrupt technique)
  455. ;======================================================================
  456. check_ems_int    proc
  457.         push    es                      ;Test for ems driver
  458.         push    di
  459.         mov     ax,3567h                ;Get EMS vector
  460.         int     21h
  461.         mov     di,0ah                  ;Using the segment from the
  462.         mov     si,offset ems_header    ;  67h vector, look at offset
  463.         mov     cx,8                    ;  0ah. Compare the next 8
  464.         cld                             ;  bytes with the expected
  465.         repe    cmpsb                   ;  EMS header. If  they are
  466.         pop     di                      ;  the same, EMS driver
  467.         pop     es                      ;  found.
  468.         jne     cemsi_error
  469.         clc
  470. cemsi_exit:
  471.         ret
  472. cemsi_error:
  473.         stc
  474.         jmp     short cemsi_exit
  475. check_ems_int    endp
  476.  
  477.  
  478. ;=============================================================================
  479. ;EMS32Upgrade
  480. ; Entry: AX - EMS 4.0 compatible function number
  481. ;        Other registers configured as needed by the fucntion
  482. ; Exit:  AH - Return code
  483. ;=============================================================================
  484. EMS32Upgrade    proc    far
  485.         pushf
  486.         push    bp
  487.         mov    bp,sp
  488.         push    ax              ;Save function number
  489.         mov    al,EMS32up_version    ;Get version
  490.         or    al,al            ;See if initialized
  491.         jne    ems32_2                 ;Yes, version already found
  492.         mov    ah,46h            ;EMS Get Version
  493.         int    67h            ;Call EMM
  494.         or    ah,ah            ;Check for error
  495.         jne    short ems32_exit
  496.         mov    EMS32up_version,al    ;Set version
  497. ems32_2:
  498.         cmp    al,40h            ;Check for version 4.0
  499.         je    ems32_call_driver
  500.         cmp    al,32h            ;Check for version 3.2
  501.         je    ems32_3
  502.         mov    ah,0ffh            ;Set bad version error code
  503.         jmp    short ems32_exit
  504. ems32_3:
  505.         mov    ax,[bp-2]        ;Get function number
  506.         cmp    ah,4eh            ;See if function 1 to 15
  507.         jbe    ems32_call_driver    ;If so, call EMM
  508.         push    bx
  509.         mov    bx,offset ems32_return
  510.         push    bx            ;Put return address on stack
  511.         mov    bx,ax                   ;Convert function into
  512.         mov    bl,bh                   ;  jump table index.
  513.         xor    bh,bh
  514.         sub    bl,50h
  515.         or    bl,bl
  516.         je    ems32_4
  517.         sub    bl,4
  518.         cmp    bl,2
  519.         jbe    ems32_4
  520.         mov    ah,84h            ;Unsupported function code
  521.         jmp    short ems32_exit
  522. ems32_4:
  523.         shl    bx,1
  524.         add    bx,offset ems32up_calltbl
  525.         push    [bx]            ;Push subroutine addr on stack
  526.         mov    bx,[bp-4]               ;Get original BX
  527.         retn                            ;Call function
  528. ems32_return:
  529.         add    sp,2            ;Pull BX off stack
  530.         jmp    short ems32_exit
  531. ems32_call_driver:
  532.         mov    ax,[bp-2]        ;Restore AX
  533.         cmp    ah,55h            ;See if map and jump
  534.         jne    ems32_5         ;If so, clean up stack since
  535.         add    sp,2                    ;  EMM will not return to
  536.         mov     [bp+4],ax        ;  this routine.
  537.         mov    ax,[bp+2]        ;Use AX and flags values to
  538.         mov    [bp+6],ax               ;  overwrite return address.
  539.         pop    bp
  540.         pop    ax            ;Clean off extra flags reg
  541.         pop    ax            ;Get back AX
  542.         popf                            ;Restore Flags
  543. ems32_5:
  544.         int    67h            ;Call EMM
  545. ems32_exit:
  546.         add    sp,2            ;Clear off original AX
  547.         pop    bp
  548.         popf
  549.         ret
  550.  
  551. ;=============================================================================
  552. ;EMSMapMultiple  simulates the Map Multiple function of the EMS 4.0 driver.
  553. ; Entry: AL - subfunction. 0 = Use physical page numbers
  554. ;                          1 = Use physical page segments
  555. ;        CX - Size of mapping array
  556. ;        DX - EMS Handle
  557. ;     DS:SI - Pointer to array of mapping structures (1 structure per page)
  558. ; Exit:  AH - Return code
  559. ;
  560. ;  Page mapping structure:
  561. ;          log_to_phys_struc  STRUC
  562. ;            log_page_number   dw  ?
  563. ;            phy_page_number   dw  ?
  564. ;          log_to_phys_struc  ENDS
  565. ;=============================================================================
  566. mapm_pfp    equ    [bp-2]            ;Pointer to page frame
  567. EMSMapMultiple    proc
  568.         push    bp
  569.         mov    bp,sp
  570.         sub    sp,2            ;Create room for local var
  571.         push    bx
  572.         push    cx
  573.         push    di
  574.         push    si
  575.         cmp    al,1            ;Check for legal subfunction
  576.         jbe    mapm_1
  577.         mov    ah,8fh            ;Subfunction code invalid
  578.         jmp    short mapm_exit
  579. mapm_1:
  580.         xor    ah,ah            ;Clear return code.
  581.         or      cx,cx            ;See if mapping 0 pages
  582.         je    mapm_exit        ;If so, exit.
  583.         xor    ah,ah
  584.         mov    di,ax            ;Copy subfunction
  585.         mov    ah,41h            ;EMS Get Page Frame segment
  586.         int    67h                     ;Call EMS driver
  587.         or    ah,ah            ;Check for error
  588.         jne    mapm_exit
  589.         mov    mapm_pfp,bx        ;Save page frame pointer
  590. mapm_loop1:
  591.         mov    ax,[si+2]        ;Get physical page
  592.         or     di,di             ;See if map by segment or num
  593.         je    mapm_4
  594.         sub    ax,mapm_pfp        ;Sub starting addr of frame
  595.         jae    mapm_3            ;If positive, continue
  596. mapm_2:
  597.         mov    ah,8bh            ;Page segment illegal RC
  598.         jmp    short mapm_exit        ;Error, goto exit
  599. mapm_3:
  600.         push    dx            ;Save handle
  601.         xor    dx,dx            ;Clear high word
  602.         mov     bx,400h            ;Divide by segment size
  603.         div    bx
  604.         or    dx,dx            ;Check for remainder. If found
  605.         pop    dx            ;  the segment was not on a
  606.         jne     mapm_2            ;  proper boundry.
  607. mapm_4:
  608.         mov    bx,[si]            ;Get logical page
  609.         mov    ah,44h            ;EMS Map page
  610.         int    67h            ;Call EMS driver
  611.         or    ah,ah            ;Check for error
  612.         jne    mapm_exit
  613.         add    si,4
  614.         loop    mapm_loop1
  615. mapm_exit:
  616.         pop    si
  617.         pop    di
  618.         pop    cx
  619.         pop    bx
  620.         add    sp,2
  621.         pop    bp
  622.         ret
  623. EMSMapMultiple    endp
  624.  
  625. ;=============================================================================
  626. ;EMSMapandJump  Simulates the Map and Jump function of the EMS 4.0 driver.
  627. ; Entry: AL - Subfunction. 0 = Use physical page numbers
  628. ;                          1 = Use physical page segments
  629. ;        DX - EMS Handle
  630. ;     DS:SI - Pointer to map and jump structure
  631. ; Exit:  AH - Return code
  632. ;
  633. ;  Map and Jump structure:
  634. ;          map_and_jump_struc    STRUC
  635. ;            target_addr          dd  ?
  636. ;            log_phys_map_len     db  ?
  637. ;            log_phys_map_ptr     dd  ?
  638. ;          map_and_jump_struc    ENDS
  639. ;
  640. ;  Page mapping structure:
  641. ;          log_phys_map_struc  STRUC
  642. ;            log_page_number   dw  ?
  643. ;            phy_page_number   dw  ?
  644. ;          log_phys_map_struc  ENDS
  645. ;=============================================================================
  646. EMSMapandJump    proc
  647.         push    bx
  648.         push    cx
  649.         push    si
  650.         push    ds
  651.         xor    cx,cx            ;Clear size
  652.         mov    cl,ds:[si+4]        ;Get size of map array
  653.         lds    si,ds:[si+5]        ;Get pointer to map array
  654.         call    EMSMapMultiple        ;Call MapMultiple to map pages
  655.         or    ah,ah            ;Check for error
  656.         pop    ds
  657.         pop    si
  658.         pop    cx
  659.         pop    bx
  660.         jne    mapandjump_exit     ;If so, error code in AH. Exit
  661.         mov    ax,ds:[si]        ;Copy jump address over return
  662.         mov    [bp+4],ax        ;  address on the stack.
  663.         mov    ax,ds:[si+2]
  664.         mov    [bp+6],ax
  665.         xor    ax,ax            ;Zero return code.
  666. mapandjump_exit:
  667.         ret
  668. EMSMapandJump     endp
  669.  
  670. ;=============================================================================
  671. ;EMSMapandCall  Simulates the Map and Call function of the EMS 4.0 driver.
  672. ; Entry: AL - Subfunction. 0 = Use physical page numbers
  673. ;                          1 = Use physical page segments
  674. ;                          2 = Get Stack space size
  675. ;        DX - EMS Handle
  676. ;        DS:SI - Pointer to map and call structure
  677. ; Exit:  AH - Return code
  678. ;
  679. ;  Map and Call structure:
  680. ;          map_and_call_struc    STRUC
  681. ;            target_addr          dd  ?
  682. ;            new_page_map_len     db  ?
  683. ;            new_page_map_ptr     dd  ?
  684. ;            old_page_map_len     db  ?
  685. ;            old_page_map_ptr     dd  ?
  686. ;          map_and_call_struc    ENDS
  687. ;
  688. ;  Page mapping structure:
  689. ;          log_phys_map_struc  STRUC
  690. ;            log_page_number   dw  ?
  691. ;            phy_page_number   dw  ?
  692. ;          log_phys_map_struc  ENDS
  693. ;=============================================================================
  694. EMSMapandCall    proc
  695.         push    ax
  696.         mov    ax,4e03h        ;Get size of save array
  697.         int     67h
  698.         or    ah,ah
  699.         pop    bx            ;Get back function
  700.         jne    mac_0
  701.         cmp    bl,2            ;Check for subfunction 2
  702.         jne    mac_1
  703.         add    al,24            ;Add aditional room on stack
  704. mac_0:
  705.         jmp    mac_exit1          ;  on the stack.
  706. mac_1:
  707.         push    si            ;Save array pointer
  708.         push    ds
  709.         push    di            ;Save registers needed for
  710.         push    es                      ;  save page map call
  711.         sub    sp,ax            ;Create room on stack
  712.         mov    di,ss            ;Point to save area on stack
  713.         mov    es,di
  714.         mov    di,sp
  715.         push    ax            ;Save size of save area
  716.         mov    ax,4e00h        ;Save page map
  717.         int    67h            ;Call EMM
  718.         or    ah,ah
  719.         je    mac_2
  720. mac_save_error:
  721.         pop    di            ;Get save area size
  722.         add    sp,di            ;Remove save area from stack
  723.         jmp    short mac_exit
  724. mac_2:
  725.         mov    ax,[bp-2]        ;Get original AX for
  726.         push    cx                      ;  subfunction.
  727.         xor    cx,cx            ;Clear size
  728.         mov    cl,ds:[si+4]        ;Get size of new array
  729.         lds    si,ds:[si+5]        ;Get pointer to new map array
  730.         call    EMSMapMultiple        ;Call MapMultiple to map pages
  731.         pop    cx
  732.         mov    ds,[bp-10]
  733.         mov    si,[bp-8]         ;Restore registers
  734.         or    ah,ah            ;Check for error
  735.         jne    mac_save_error         ;If so, error code in AH.
  736.         mov    es,[bp-14]
  737.         mov    di,[bp-12]
  738.         mov    ax,[bp+2]        ;Get flags off stack
  739.         push    ax
  740.         popf                ;Restore flags
  741.                 push    bp            ;Save my BP
  742.         mov    bp,[bp]            ;Restore original BP
  743.         mov    ah,0            ;Set return code
  744.         call    dword ptr ds:[si]    ;Call user routine
  745.         pop    ax            ;Get back BP used by routine
  746.         xchg    bp,ax              ;Put returned BP on stack in
  747.         mov    [bp],ax                 ;  place of original BP
  748.         pushf                ;Put all 16 bits of the flags
  749.         pop    ax                      ;  register in AX.
  750.         mov    [bp+2],ax        ;Save new flag state on stack
  751.         mov    [bp-12],di        ;Save new ES:DI
  752.         mov    [bp-14],es
  753.         mov    di,si            ;Save new DS:SI
  754.             push    ds
  755.         pop    es
  756.         mov    si,ss            ;Point to save area on stack
  757.         mov    ds,si
  758.         mov    si,sp
  759.         inc    si            ;Move past save area size
  760.         inc    si
  761.         mov    ax,4e01h        ;Restore page map
  762.         int    67h
  763.         pop    si                      ;Get size of save area
  764.                 add    sp,si            ;Remove save area from stack
  765.         push    es
  766.         pop    ds
  767.         mov    si,di
  768.         or    ah,ah
  769.         jne    mac_exit
  770.         push    cx                      ;Save working registers
  771.         push    si
  772.         push    ds
  773.         mov    si,[bp-8]        ;Get pointer to structure off
  774.         mov    ds,[bp-10]              ;  the stack
  775.         xor    cx,cx            ;Clear size
  776.         mov    ax,[bp-2]        ;Restore subfunction
  777.         mov    cl,ds:[si+9]        ;Get size of old array
  778.         lds    si,ds:[si+10]        ;Get pointer to old map array
  779.         call    EMSMapMultiple        ;Call MapMultiple to map pages
  780.         pop    ds
  781.         pop    si
  782.         pop    cx
  783. mac_exit:
  784.         pop    es
  785.         pop    di
  786.         add    sp,4            ;Clear off old SI and DS
  787. mac_exit1:
  788.         ret
  789. EMSMapandCall     endp
  790.  
  791. EMS32Upgrade    endp
  792.  
  793.         end
  794.