.model medium, basic
.stack 10h
.386
.data
        XMSAdd dd ?
.code

public VSAllocateXMS
public VSDeallocateXMS
public VSDetectXMS
public VSFreeXMS
public VSMoveXMS
public VSResizeXMS
public VSTotalXMS

;=======This checks for XMS existence========================================
VSDetectXMS proc
      mov ax, 4300h                   ;Check for XMS
      int 2fh
      cmp al, 80h                     ;Does AL=80h?
      jg detect                       ;If not, go to detect

      inc al                          ;AL=81h
      mov cl, al                      ;Store AL in CL
      mov al, 10h                     ;Get the address of the XMS driver
      int 2fh
      mov word ptr [XMSAdd], bx
      mov word ptr [XMSAdd+2], es
      mov al, cl                      ;Retrive AL
   detect:
      sub al, 80h                     ;AX: 1=success, 0=error
      xor ah, ah                      
      ret                             ;End sub
VSDetectXMS endp

;=======This allocates a block of XMS========================================
VSAllocateXMS proc
      push bp
      mov bp, sp

      mov ah, 9                       ;Call XMS driver to allocate handle
      mov dx, [bp+6]
      call [XMSAdd]

      cmp ax, 1   
      jnz allocate                    ;AX: 1=success, 0=error
      mov ax, dx
   allocate:

      pop bp
      ret 2
VSAllocateXMS endp

;=======This deallocates a block of XMS======================================
VSDeallocateXMS proc
      push bp
      mov bp, sp

      mov ah, 0ah                     ;Call XMS driver to deallocate handle
      mov dx, [bp+6]
      call [XMSAdd]                   ;AX: 1=success, 0=error

      pop bp
      ret 2
VSDeallocateXMS endp

;=======This resizes an XMS handle===========================================
VSResizeXMS proc
      push bp
      mov bp, sp

      mov ah, 0fh        ;Call XMS driver to resize handle
      mov dx, [bp+8]     ;handle
      mov bx, [bp+6]     ;#KB
      call [XMSAdd]      ;AX: 1=success, 0=error

      pop bp
      ret 4
VSResizeXMS endp

;=======This moves memory====================================================
VSMoveXMS proc
      push ds

      mov ax, ss
      mov ds, ax
      mov si, sp
      add si, 6                       ;DS:[SI]=SS:[BP+8] <-data from QB

      mov ah, 0bh                     ;Call XMS driver to move mem
      call [XMSAdd]                   ;AX: 1=success, 0=error

      pop ds
      ret 16
VSMoveXMS endp

;=======This returns the amount of free XMS in KB.===========================
VSFreeXMS proc
      mov ah, 08h                     ;Calls XMS driver to get XMS info
      call [XMSAdd]
      ret
VSFreeXMS endp

;=======This returns the total amount of XMS in KB.==========================
VSTotalXMS proc
      mov ah, 08h                     ;Calls XMS driver to get XMS info
      call [XMSAdd]
      mov ax, dx
      ret
VSTotalXMS endp

end
