        .model tpascal
        include se.asm
        .data
        extrn ovrcodelist:word
        extrn ovrheaporg:word
        extrn ovrdoshandle:word
        extrn ovremshandle:word
        extrn exitproc:dword
        extrn prefixseg:word
        extrn ovrresult:word
        extrn ovrreadbuf:dword
        extrn ovremspages:word
emsseg  dw ?
saveexit        dd ?
        .code
        public ovrinitems
emsname db 'EMMXXXX0'
ovrinitems      proc far
        xor ax,ax
        cmp ax,ovrdoshandle
        jne @@1
        dec ax
        jmp short @@5
@@1:    call checkems
        jz @@2
        mov ax,-5
        jmp short @@5
@@2:    call allocems
        jnc @@3
        mov ax,-6
        jmp short @@5
@@3:    call switchtoems
        jnc @@4
        mov dx,ovremshandle
        mov ah,45h
        int 67h
        mov ax,-4
        jmp short @@5
@@4:    mov bx,ovrdoshandle
        mov ah,dosclose
        int dos
        mov word ptr ovrreadbuf[0],offset ovrreadems
        mov word ptr ovrreadbuf[2],cs
        les ax,exitproc
        mov word ptr saveexit[0],ax
        mov word ptr saveexit[2],es
        mov word ptr exitproc[0],offset newexit
        mov word ptr exitproc[2],cs
        xor ax,ax
@@5:    mov ovrresult,ax
        ret
ovrinitems      endp
newexit proc far
        mov dx,ovremshandle
        mov ah,45h
        int 67h
        les ax,saveexit
        mov word ptr exitproc[0],ax
        mov word ptr exitproc[2],es
        ret
newexit endp
checkems        proc near
        mov ax,dosgetint*256+67h
        int dos
        mov cx,8
        mov si,offset emsname
        mov di,0ah
        push ds cs
        pop ds
        cld
        repe cmpsb
        pop ds
        ret
checkems        endp
allocems        proc near
        mov ah,41h
        int 67h
        mov emsseg,bx
        mov ax,16383
        xor dx,dx
        mov bx,ovrcodelist
@@1:    add bx,prefixseg
        add bx,10h
        mov es,bx
        add ax,es:ovcodesize
        adc dx,0
        mov bx,es:ovlink
        or bx,bx
        jnz @@1
        mov bx,16384
        div bx
        mov bx,ax
        mov ah,43h
        int 67h
        shl ah,1
        jc @@2
        mov ovremspages,bx
        mov ovremshandle,dx
@@2:    ret
allocems        endp
switchtoems     proc near
        push bp
        mov bp,sp
        mov dx,ovremshandle
        mov ah,47h
        int 67h
        mov ax,ovrcodelist
        xor cx,cx
@@1:    add ax,prefixseg
        add ax,10h
        mov es,ax
        push ax
        inc cx
        mov ax,es:ovlink
        or ax,ax
        jnz @@1
        xor bx,bx
        xor di,di
@@2:    pop es
        push cx
        mov ax,ovrheaporg
        mov es:ovsegment,ax
        mov es:ovemspage,bx
        mov es:ovemsoffset,di
        push bx di es es
        call ovrreadbuf
        pop es di bx
        mov es:ovsegment,0
        neg ax
        jc @@3
        call puttoems
        jc @@3
        pop cx
        loop @@2
@@3:    pushf
        mov dx,ovremshandle
        mov ah,48h
        int 67h
        popf
        mov sp,bp
        pop bp
        ret
switchtoems     endp
puttoems        proc near
        mov dx,es:ovcodesize
        xor si,si
@@1:    or di,di
        jnz @@2
        push dx
        mov dx,ovremshandle
        mov ax,4400h
        int 67h
        pop dx
        shl ah,1
        jc @@5
@@2:    mov cx,16384
        sub cx,di
        cmp cx,dx
        jb @@3
        mov cx,dx
@@3:    sub dx,cx
        push ds es
        mov es,emsseg
        mov ds,ovrheaporg
        cld
        rep movsb
        pop es ds
        cmp di,16384
        jne @@4
        inc bx
        xor di,di
@@4:    or dx,dx
        jnz @@1
@@5:    ret
puttoems        endp
ovrreadems      proc far
        mov bx,sp
        mov es,ss:[bx+4]
        mov dx,ovremshandle
        mov ah,47h
        int 67h      ;LIM EMS - SAVE MAPPING CONTEXT
        mov bx,es:ovemspage
        mov dx,es:ovcodesize
        mov si,es:ovemsoffset
        xor di,di
@@1:    mov cx,16384
        sub cx,si
        cmp cx,dx
        jb @@2
        mov cx,dx
@@2:    sub dx,cx
        push dx
        mov dx,ovremshandle
        mov ax,4400h
        int 67h   ;LIM EMS - MAP MEMORY
        pop dx
        or ah,ah
        jnz @@3
        push ds es
        mov ds,emsseg
        mov es,es:ovsegment
        cld
        rep movsb
        pop es ds
        inc bx
        xor si,si
        or dx,dx
        jnz @@1
@@3:    mov al,ah
        xor ah,ah
        push ax
        mov dx,ovremshandle
        mov ah,48h ; LIM EMS - RESTORE MAPPING CONTEXT
        int 67h
        pop ax
        ret 2
ovrreadems      endp
        end

