; XMS routines to get available UMB's and HMA,
; and allocate extended memory.
; Written from the XMS 3.0 specification.
; (C) 1993 Johan. K. Reinalda, WG7J

include asmglobal.h

.data
XMS_Entry  dd   1

.code
public Installed_XMS
public Request_UMB,Release_UMB
public Request_HMA,Release_HMA
public Query_XMS,Total_XMS
public Alloc_XMS,Free_XMS
public Move_XMS

Installed_XMS proc
    mov     ax,4300h
    int     2Fh
    cmp     al,80h
    jne     NoXMSDriver
; Get the address of the driver's control function
    mov     ax,4310h
    int     2Fh
    mov     word ptr [XMS_Entry],bx      ;XMS_Entry is function entry point
    mov     word ptr [XMS_Entry+2],es
    mov     ax, 1
    ret
NoXMSDriver:
    xor     ax, ax
    ret
Installed_XMS endp


Request_UMB proc
    arg sz:word

    mov ah, 10h
    mov dx, sz
    call [XMS_Entry]
    cmp ax, 1
    jne request_failed
    mov ax, bx      ; UMB segment in dx
    jmp request_done
request_failed:
    mov ax, dx      ; set actual size
    mov dh, bl      ; return error code
request_done:
    ret
Request_UMB endp

Release_UMB proc
    arg block:word

    mov dx, block
    mov ah, 11h
    call [XMS_Entry]
    cmp ax, 1
    jne release_failed
    xor ax, ax
    xor dx, dx
    jmp release_done
release_failed:
    mov dh, bl          ; return error in high byte
release_done:
    ret
Release_UMB endp

Request_HMA proc
    mov ah, 01h
    mov dx, 0ffffh      ; we're an application
    call [XMS_Entry]
    ret
Request_HMA endp

Release_HMA proc
    mov ah, 02h
    call    [XMS_Entry]
    ret
Release_HMA endp

Query_XMS proc
    mov ah, 8
    call    [XMS_Entry]
	xor	dx, dx
    or  ax, ax
    jnz  QLSuccess
	mov	dh, bl
QLSuccess:
    ret
Query_XMS endp

Total_XMS proc
	mov	ah, 8
    call    [XMS_Entry]
    xor ax, ax
    mov ax, dx
    mov dx, 0
    jnz QTSuccess
	mov	dh, bl
QTSuccess:
    ret
Total_XMS endp

Alloc_XMS proc
    arg sz:word

	mov	ah, 9
    mov dx, sz
    call    [XMS_Entry]
    xor ax, ax
    mov ax, dx
    mov dx, 0
    jnz AESuccess
	mov	dh, bl
AESuccess:
    ret
Alloc_XMS endp

Free_XMS proc
    arg handle:word

    mov ah, 0Ah
    mov dx, handle
    call    [XMS_Entry]
	xor	dx, dx
	dec	ax
    jz  FSuccess
    mov dl, bl
FSuccess:
    ret
Free_XMS endp

Move_XMS proc
    arg buf:dword

    push ds
    push si

; DS:SI = pointer to XMS move stucture
    lds si, buf
    mov ah, 0bh
    call    [XMS_Entry]
    xor dx, dx
	dec	ax
    jz  MSuccess
	mov	dh, bl
MSuccess:
    pop si
    pop ds
    ret
Move_XMS endp

END

