Code:
'------------------------------------------------------------------------------
'      Unit: Emssubs2.pbl
'     Zweck: Subset der EMS v3 und EMS v4-Funktionen
'            Weiterentwickelt aus dem Assembler-Modul Emssubs1.asm,
'            weitgehend aufwärtskompatibel
'     Stand: 23.07.98
'   Version: 1.00 20.04.96
'            1.01 23.07.98 Recompile wg. Änderung POINTER2-Unit.
'     Autor: M.Hoffmann
'   Sprache: PowerBASIC 3.x
'  Benötigt: Unit 'Pointer'
'  Historie: ACHTUNG: Funktionsrückgaben geändert (-ErrCode anstelle von -1).
'            Aus Kompat.gründen bleibt EmsErrCode erhalten, zusätzlich liegt
'            die EMM-Funktion 40 (Status prüfen) als EmmState vor.
'   Sinnvolle Erweiterung: Funktion zum Kopieren von Speicherbereichen (0x57).
'   EMSErrCode geht noch nicht (liefert IMMER 0).
'   Fehler im Handbuch 'PC INTERN 3.0':
'    Seite# 1326, Fn 67 53 01: Statt ES [img]http://www.powerbasic.com/support/forums/biggrin.gif[/img]I --> DS:SI
'    Seite# 1319, Fn 67 4E 01: Statt ES [img]http://www.powerbasic.com/support/forums/biggrin.gif[/img]I --> DS:SI
' { weitere Verbesserungen möglich: @POINTER, PUSHF/POPF... }
'------------------------------------------------------------------------------
' c: emssubs2.pbu      4336  20.04.96  22:18  v1.00
' c: emssubs2.pbu      4332  23.07.98  15:26  v1.01

$compile  unit
$cpu      80386
$debug    map-,pbdebug-,path-,unit-
$dim      all
$error    all-
$event    off
$float    emulate
$optimize size
$option   cntlbreak-,gosub-,signed-
$static

dim gEmsErr as shared integer

$if 0
FUNKTION                      AUFRUF              NORMALES ERGEBNIS FEHLER
----------------------------- ------------------- ----------------- ---------
EMS-Verfügbarkeit prüfen      EmsCheck            0                 -err,-1
EMS-Seitenrahmenadr. ermittel EmsSegment          Segmentadresse    -err
Anzahl der freien Seiten erm. EmsPages            Anz. FREIE Seiten -err
Anzahl der gesamten Seiten    EmsMemory           Anz. ALLER Seiten -err
Seiten anfordern              EmsAlloc(Pgs)       Handle            -err
Seiten einblenden             EmsMapIn(Hdl,PP,LP) 0                 -err
Seiten ausblenden             EmsMapOut(Hdl,PP)   0                 -err
Alle Seiten zum Hdl freigeb.  EmsRelease(Hdl)     0                 -err
EMS-Version prüfen            EmsVersion          Version           -err
Name für Handle setzen        EmsSetName(hdl,nam) 0                 -err
Name über Handle ermitteln    EmsGetName(hdl,nam) 0                 -err
Handle über Name ermitteln    EmsGetHandle(nam)   Handle            -err
Letztes Funktionsergebnis     EmsErrCode          Letztes Funkt.Ergebnis
Managerstatus holen           EmsState            Managerstatus
Seitentabelle sichern         EmsSavePTab(buf)    0                 -err
Seitentabelle zurückladen     EmsRestPTab(buf)    0                 -err
Pgs = Anzahl gewünschter Seiten
Hdl = Handle
PP  = Physical Page (0...3)
LP  = Logical Page (0...Pgs-1)
$endif

'---Externer Code (POINTER1.PBU)-----------------------------------------------

declare function GetIntVec (byval byte)  as dword
declare function Segment   (byval dword) as word

'===Funktionen=================================================================

'---Prüfen EMS-Verfügbarkeit---------------------------------------------------

function EmsCheck local public as integer
   function = -1 ' Default: Treiber nicht geladen
   gEmsErr  = -1
   def seg = Segment(GetIntVec(&h67))
   if peek$(&ha,8) = "EMMXXXX0" then
      def seg
      ! mov ax,&h4000
      ! int &h67
      ! mov al,ah
      ! xor ah,ah
      ! neg ax
      ! mov function,ax
      ! mov gEmsErr,ax
   else
      def seg
   end if
end function

'---Adresse des EMS-Seitenrahmens (Pageframe) ermitteln------------------------

function EmsSegment local public as integer
   ! mov ax,&h4100
   ! int &h67
   ! or ah,ah
   ! jz EmsSegmentOk
   ! xor bh,bh
   ! mov bl,ah
   ! neg bx
EmsSegmentOk:
   ! mov function,bx
   ! mov gEmsErr,bx
end function

'---Ermitteln der VERFÜGBAREN freien EMS-Seiten--------------------------------

function EmsPages local public as integer
   ! mov ax,&h4200
   ! int &h67
   ! or ah,ah
   ! jz EmsPagesOk
   ! xor bh,bh
   ! mov bl,ah
   ! neg bx
EmsPagesOk:
   ! mov function,bx
   ! mov gEmsErr,bx
end function

'---Ermitteln ALLER EMS-Seiten-------------------------------------------------

function EmsMemory local public as integer
   ! mov ax,&h4200
   ! int &h67
   ! or ah,ah
   ! jz EmsMemoryOk
   ! xor dh,dh
   ! mov dl,ah
   ! neg dx
EmsMemoryOk:
   ! mov function,dx
   ! mov gEmsErr,dx
end function

'---EMS-Seiten anfordern-------------------------------------------------------

function EmsAlloc (byval pages as integer) local public as integer
   ! mov ax,&h4300
   ! mov bx,pages
   ! int &h67
   ! or ah,ah
   ! jz EmsAllocOk
   ! xor dh,dh
   ! mov dl,ah
   ! neg dx
EmsAllocOk:
   ! mov function,dx
   ! mov gEmsErr,dx
end function

'---Alle einem Handle zugeordnete Seiten freigeben-----------------------------

function EmsRelease (byval handle as integer) local public as integer
   ! mov ax,&h4500
   ! mov dx,handle
   ! int &h67
   ! mov al,ah
   ! xor ah,ah
   ! neg ax
   ! mov function,ax
   ! mov gEmsErr,ax
end function

'---logische in phys. Seite einblenden (einlagern)-----------------------------

function EmsMapIn (byval handle as integer,_
                   byval pPage  as integer,_
                   byval lPage  as integer) local public as integer
   ! mov bx,lPage
   ! mov al,pPage
   ! mov dx,handle
   ! mov ah,&h44
   ! int &h67
   ! mov al,ah
   ! xor ah,ah
   ! neg ax
   ! mov function,ax
   ! mov gEmsErr,ax
end function

'---Phys. Seite ausblenden (Zuordnung zur logischen Seite aufheben)------------

function EmsMapOut (byval handle as integer,_
                    byval pPage  as integer) local public as integer
   ! mov bx,&hffff
   ! mov al,pPage
   ! mov dx,handle
   ! mov ah,&h44
   ! int &h67
   ! mov al,ah
   ! xor ah,ah
   ! neg ax
   ! mov function,ax
   ! mov gEmsErr,ax
end function

'---EMM-Version ermitteln------------------------------------------------------

function EmsVersion local public as integer
   dim temp as integer
   ! mov ax,&h4600
   ! int &h67
   ! or ah,ah
   ! jz EmsVersionOk
   ! mov al,ah
   ! xor al,al
   ! neg ax
   ! mov function,ax
   ! mov gEmsErr,ax
   exit function
EmsVersionOk:
   ! mov temp,ax
   temp = (temp and &b1111)+(temp\15)*10
   function = temp
   gEmsErr  = temp
end function

'---Expanded Memory Manager-Status ermitteln-----------------------------------

function EmsState local public as integer ' Code wird NEGiert!
   ! mov ax,&h4000
   ! int &h67
   ! mov al,ah
   ! xor ah,ah
   ! neg ax
   ! mov function,ax
   ! mov gEmsErr,ax
end function

'---Letzten EMM-Fehlercode ermitteln (Ersatz glob. Var EmsErrCode, Kompatibil.)

function EmsErrCode local public as integer
   function = gEmsErr
end function

'---Name für Handle setzen-----------------------------------------------------

function EmsSetName (byval handle as integer,_
                     hname        as string) local public as integer
   dim tn as local string*8
   dim ts as local word
   dim tp as local word
   tn = hname
   ts = varseg(tn)
   tp = varptr(tn)
   ! push ds
   ! push si
   ! mov ax,&h5301
   ! mov dx,handle
   ! mov ds,ts
   ! mov si,tp
   ! int &h67
   ! pop si
   ! pop ds
   ! mov al,ah
   ! xor ah,ah
   ! neg ax
   ! mov function,ax
   ! mov gEmsErr,ax
end function

'---Name über Handle ermitteln-------------------------------------------------

function EmsGetName (byval handle as integer,_
                     hname        as string) local public as integer
   dim tn as local string*8
   dim ts as local word
   dim tp as local word
   ts = varseg(tn)
   tp = varptr(tn)
   ! push di
   ! mov ax,&h5300
   ! mov dx,handle
   ! mov es,ts
   ! mov di,tp
   ! int &h67
   ! pop di
   ! or ah,ah
   ! jz EmsGetNameOk
   tn = ""
EmsGetNameOk:
   hname = tn
   ! mov al,ah
   ! xor ah,ah
   ! neg ax
   ! mov function,ax
   ! mov gEmsErr,ax
end function

'---Handle über Name ermitteln-------------------------------------------------

function EmsGetHandle (hname as string) local public as integer
   dim tn as local string*8
   dim ts as local word
   dim tp as local word
   tn = hname
   ts = varseg(tn)
   tp = varptr(tn)
   ! push ds
   ! push si
   ! mov ax,&h5401
   ! mov ds,ts
   ! mov si,tp
   ! int &h67
   ! pop si
   ! pop ds
   ! or ah,ah
   ! jz EmsGetHandleOk
   ! mov dl,ah
   ! xor dh,dh
   ! neg dx
EmsGetHandleOk:
   ! mov function,dx
   ! mov gEmsErr,dx
end function

'---Seitentabelle sichern------------------------------------------------------

function EmsSavePTab (savetab as string) local public as integer
   dim ts as local word
   dim tp as local word
   dim ps as local integer
   ! mov ax,&h4e03
   ! int &h67
   ! or ah,ah
   ! jz EmsSavePTabOk
   ! jmp EmsSavePTabX
EmsSavePTabOk:
   ! mov ps,al
   savetab = space$(ps) ' Achtung: Stringsegmentgröße!!
   ts = strseg(savetab)
   tp = strptr(savetab)
   ! push di
   ! mov ax,&h4e00
   ! mov es,ts
   ! mov di,tp
   ! int &h67
   ! pop di
EmsSavePTabX:
   ! mov al,ah
   ! xor ah,ah
   ! neg ax
   ! mov function,ax
   ! mov gEmsErr,ax
end function

'---Seitentabelle zurückladen--------------------------------------------------

function EmsRestPTab (savetab as string) local public as integer
   dim ts as local word
   dim tp as local word
   ts = strseg(savetab)
   tp = strptr(savetab)
   ! push ds
   ! push si
   ! mov ax,&h4e01
   ! mov ds,ts
   ! mov si,tp
   ! int &h67
   ! pop si
   ! pop ds
   ! mov al,ah
   ! xor ah,ah
   ! neg ax
   ! mov function,ax
   ! mov gEmsErr,ax
end function

'==============================================================================
------------------