home *** CD-ROM | disk | FTP | other *** search
- program Ems_Test;
- { ***************************************************************
- * Dieses Programm demonstriert die Zugriffsmöglichkeiten *
- * auf Speichererweiterungen nach dem LIM-EMS-Standard *
- * ("Lotus Intel Microsoft Expanded Memory"). Es verwendet *
- * keine der 'höheren' EMS-Funktionen und ist deshalb auch auf *
- * Systemen lauffähig, die mit EMS-Versionen vor 4.0 arbeiten. *
- ***************************************************************
-
- Geschrieben von:
- Peter Immarco
- Thought Dynamics
- Manhattan Beach, CA
- Compuserve ID# 73770,123
- *** Public Domain ***
-
- Die Wiedergabe erfolgt mit freundlicher Genehmigung des Autors.
- }
-
- { Dieses Programm führt die folgenden Schritte aus:
- * Prüfung, ob der LIM Expanded Memory Manager (EMM) im Hauptspeicher
- installiert wurde
- * Ausgabe der Versionsnummer des EMM
- * Bestimmung, ob genügend Speicherblocks (mit jeweils 16 KByte) EMS
- zur freien Verfügung stehen, Ausgabe der Anzahl freier/belegter Blocks
- * Anforderung einer bestimmten Anzahl von Speicherblocks
- * Zuordnung einer logischen Seite zu einem der angeforderten physikalischen
- Speicherblocks, Ausgabe der entsprechenden EMS-Basisadresse
- * Ausführung eines einfachen Lese- und Schreibtests in dieser Seite
- * Rückgabe des belegten Speicherplatzes an den EMM und Ende.
-
-
- Alle Aufrufe liefern das Ergebnis bzw. den Statuscode der aufgerufenen
- EMM-Funktion als Integerwert zurück. Für Statuscodes <> 0 (d.h. Fehler)
- führt das Programm eine einfache Fehlerbehandlung aus und bricht dann ab.
- }
-
- uses Crt, Dos;
-
- type
- ST3 = string[3];
- ST80 = string[80];
- ST5 = string[5];
-
- const
- EMM_INT = $67;
- DOS_Int = $21;
- GET_PAGE_FRAME = $41;
- GET_UNALLOCATED_PAGE_COUNT= $42;
- ALLOCATE_PAGES = $43;
- MAP_PAGES = $44;
- DEALLOCATE_PAGES = $45;
- GET_VERSION = $46;
-
- STATUS_OK = 0;
-
- { Wir gehen davon aus, daß wir nur eine einzige EMS-Seite für unser
- Programm benötigen }
- APPLICATION_PAGE_COUNT = 1;
-
- var
- Regs: Registers;
- Emm_Handle,
- Page_Frame_Base_Address,
- Pages_Needed,
- Physical_Page,
- Logical_Page,
- Offset,
- Error_Code,
- Pages_EMS_Avail,
- Total_EMS_Pages,
- Available_EMS_Pages: Word;
- Version_Number,
- Pages_Number_String: ST3;
- Verify: Boolean;
-
- { * --------------------------------------------------------- * }
- function Hex_String(Number: Word): ST5;
- { Konvertiert den übergebenen Wert (Typ Word) in einen String mit vier
- Hexadezimalzeichen (und nötigenfalls führenden Nullen) }
- function Hex_Char(Number: Word): Char;
- begin
- if Number<10 then Hex_Char:=Char(Number+48)
- else Hex_Char:=Char(Number+55);
- end; { Hex_Char }
-
- var
- S: ST5;
- begin
- S:='';
- S:=Hex_Char( (Number shr 1) div 2048);
- Number:=( ((Number shr 1) mod 2048) shl 1)+ (Number and 1) ;
- S:=S+Hex_Char(Number div 256);
- Number:=Number mod 256;
- S:=S+Hex_Char(Number div 16);
- Number:=Number mod 16;
- S:=S+Hex_Char(Number);
- Hex_String:=S+'h';
- end; { Hex_String }
-
-
- function Emm_Installed: Boolean;
- { Prüft, ob der Expanded Memory Manager (EMM) installiert (d.h in den
- Hauptspeicher geladen) ist. Falls ja, sollte sich der String 'EMMXXXX0'
- auf der Offset-Adresse $0010 des Segments befinden, auf den der EMM-
- Interrupt-Vektor ($67) zeigt.
- Liefert TRUE, wenn EMM installiert, ansonsten FALSE }
- var
- Emm_Device_Name : string[8];
- Int_67_Device_Name : string[8];
- Position : Word;
- Regs : registers;
-
- begin
- Int_67_Device_Name:='';
- Emm_Device_Name :='EMMXXXX0';
- with Regs do
- begin
- { Ermittlung des Segments, auf den der Interrupt-Vektor $67 zeigt
- über die DOS-Funktion $35 ("Get Interrupt Vector") }
- AH:=$35; AL:=EMM_INT;
- Intr(DOS_int,Regs); { liefert das Segment im ES-Register zurück }
- for Position:=0 to 7 do
- Int_67_Device_Name:= { Auslesen von 8 Bytes ab dem Offset $0A }
- Int_67_Device_Name + Chr(Mem[ES:$0A+Position]);
- Emm_Installed := (Int_67_Device_Name = Emm_Device_Name);
- end; { with Regs do }
- end; { Emm_Installed }
-
-
- function EMS_Pages_Avail (var Total_EMS_Pages,Pages_Avail: Word): Word;
- { Ermittelt die Gesamtzahl der EMS-Seiten und die Anzahl der für uns
- verfügbaren Seiten }
- var
- Regs: Registers;
- begin
- with Regs do
- begin
- AH:=Get_Unallocated_Page_Count; { EMM-Funktion: freie Seiten ermitteln }
- Intr(EMM_INT,Regs); { EMM-Aufruf }
- Pages_Avail:=BX; { liefert freie Seiten in BX zurück }
- Total_EMS_Pages:=DX; { und Gesamtzahl der Seiten in DX }
- EMS_Pages_Avail:=AH { sowie einen eventuellen Fehlercode in AH }
- end; { with Regs }
- end;
-
-
- function Alloc_EMS_Pages (Pages_Needed: Word; var Handle: Word): Word;
- { Fordert eine oder mehrere EMS-Seiten über einen EMM-Aufruf an }
- var
- Regs: Registers;
- begin
- with Regs do
- begin
- AH:= Allocate_Pages; { EMM-Funktion: Speicherseiten belegen }
- BX:=Pages_Needed; { BX: Anzahl der gewünschten Seiten }
- intr(EMM_INT,Regs); { EMM-Aufruf }
- Handle:=DX; { liefert einen Handle in DX zurück }
- Alloc_EMS_Pages:=AH; { und einen evtl. Fehlercode in AH }
- end; { with Regs }
- end;
-
- function Map_EM_Pages (Handle,Logical_Page,Physical_Page: Word): Word;
- { Ordnet einer physikalischen EMS-Seite (die via Alloc_EMS_Pages belegt
- wurde) eine logische Speicherseite zu }
- var
- Regs: Registers;
- begin
- with Regs do
- begin
- AH:=Map_Pages; { EMM-Funktion: physikalisch/logische Zuordnung }
- AL:=Physical_Page; { AL: physikalische Nummer }
- BX:=Logical_Page; { BX: logische Seitennummer }
- DX:=Handle; { DX: Handle }
- Intr(EMM_INT,Regs); { EMM-Aufruf }
- Map_EM_Pages:=AH; { liefert einen eventueller Fehlercode in AH }
- end; { with Regs }
- end;
-
-
- function Get_Page_Frame_Base_Address (var Page_Frame_Address: Word): Word;
- { Liefert die physikalische Basisadresse (= Segment) zurück }
- var
- Regs: Registers;
- begin
- with Regs do
- begin
- AH:=Get_Page_Frame; { EMM-Funktion: Basisadresse ermitteln }
- Intr(EMM_INT,Regs); { EMM-Aufruf }
- Page_Frame_Address:=BX; { liefert die Basisadresse in BX zurück }
- Get_Page_Frame_Base_Address:=AH; { und einen evtl. Fehlercode in AH }
- end; { with Regs }
- end;
-
- function Deallocate_EM_Pages (Handle: Word): Word;
- { Gibt die zuvor belegten EMS-Seiten wieder frei }
- var
- Regs: Registers;
- begin
- with Regs do
- begin
- AH:=DEALLOCATE_PAGES; { EMM-Funktion: Freigabe }
- DX:=Emm_Handle; { DX: Handle für die frezugebenden Seiten }
- Intr(EMM_INT,Regs); { EMM-Aufruf }
- Deallocate_EM_Pages:=AH; { evtl. Fehlercode in AH }
- end; { with Regs }
- end;
-
- function Get_Version_Number(var Version_String: ST3): Word;
- { Liefert die EMM-Versionsnummer als String (mit 3 Zeichen) zurück }
- var
- Regs: Registers;
- Word_Part,Fractional_Part: Char;
- begin
- with Regs do
- begin
- AH:=GET_VERSION; { EMM-Funktion: Versionsnummer }
- Intr(EMM_INT,Regs); { EMM-Aufruf }
- if AH=STATUS_OK then { wenn kein Fehler: }
- begin
- { Bits 7..4 von AL: Haupt-Versionsnummer, Bits 3..0: Neben-Version }
- Word_Part := Char( AL shr 4 + 48); { Konvertierung in ein Zeichen }
- Fractional_Part:= Char( AL and $F +48); { dito für Neben-Versionsnummer }
- Version_String:= Word_Part+'.'+Fractional_Part; { z.B. '3.1' }
- end;
- Get_Version_Number:=AH; { eventueller Fehlercode... }
- end; { with Regs }
- end;
-
- procedure Error(Error_Message: ST80; Error_Number: Word);
- { Gibt die als Error_Message übergebene Meldung und die als Error_Number
- übergebene Zahl (hexadezimal) aus und bricht das Programm mit einem
- Exit-Code von 1 ab. }
- begin
- Writeln(Error_Message);
- Writeln(' Fehlernummer: ',Hex_String(Error_Number) );
- Writeln('EMS-Testprogramm abgebrochen.');
- Halt(1);
- end;
-
- { *************************************************************** }
- { *************************************************************** }
- begin { Hauptprogramm }
- ClrScr;
- Window(5,2,77,22);
-
- if not (Emm_Installed) then { EMM installiert? }
- begin
- Writeln('Der LIM Expanded Memory Manager ist nicht installiert.');
- Halt(1); { Abbruch mit Exitcode 1 }
- end;
-
- { Ermittlung der EMM-Versionsnummer und Ausgabe }
- Error_Code:= Get_Version_Number(Version_Number);
- if Error_Code<>STATUS_OK then
- Error('Fehler bei der Ermittlung der EMM-Versionsnummer.', Error_code)
- else Writeln('EMM-Versionsnmummer: ', Version_Number);
- Writeln;
-
- { Ermittlung der Gesamtzahl EMS-Seiten und der Anzahl freier Seiten }
- Pages_Needed:=APPLICATION_PAGE_COUNT;
- Error_Code:= EMS_Pages_Avail(Total_EMS_Pages,Available_EMS_Pages);
- if Error_Code<>STATUS_OK then
- Error('Fehler beim Versuch, die Anzahl freier EMS-Seiten zu ermitteln.',
- Error_Code);
-
- Writeln('Das System verfügt insgesamt über ',Total_EMS_Pages,
- ' EMS-Seiten.');
- Writeln('- ',Available_EMS_Pages,
- ' davon sind für unser Programm verfügbar.');
- Writeln;
-
- if Pages_Needed>Available_EMS_Pages then { nicht genug freie Seiten? }
- begin
- Str(Pages_Needed,Pages_Number_String);
- Error('Unser Programm erwartet allerdings '+Pages_Number_String+
- ' EMS-Seiten. ', Error_Code);
- end;
-
- { Tatsächliche Belegung der EMS-Speicherseiten }
- Error_Code:= Alloc_EMS_Pages(Pages_Needed,Emm_Handle);
- Str(Pages_Needed,Pages_Number_String);
- if Error_Code<>STATUS_OK then
- Error('Fehler beim Versuch, '+Pages_Number_String+
- ' EMS-Seiten zu belegen.',Error_Code);
- Writeln(APPLICATION_PAGE_COUNT,
- ' EMS-Seite(n) für unser Programm belegt!');
- Writeln;
-
- { Zuordnung der logischen Seiten auf physikalische Seiten (für unser
- Testprogramm läuft das auf eine einzige Zuordnung hinaus) }
- Logical_Page :=0; Physical_Page:=0;
- Error_Code:= Map_EM_Pages(Emm_Handle,Logical_Page,Physical_Page);
- if Error_Code<>STATUS_OK then
- Error('Fehler bei der logisch/physikalischen Zuordnung.', Error_Code);
-
- Writeln('Logische Seite ',Logical_Page, ' wurde der physikalischen Seite ',
- Physical_Page, ' zugeordnet.');
- Writeln;
-
- { Ermittlung der Basisadresse }
- Error_Code:= Get_Page_Frame_Base_Address(Page_Frame_Base_Address);
- if Error_Code<>STATUS_OK then
- Error('Fehler bei der Ermittlung der Basisadresse.', Error_Code);
- Writeln('Die Basisadresse der belegten Speicherseite(n) ist: ' +
- Hex_String(Page_Frame_Base_Address) );
- Writeln;
-
- { Schreiben eines Bitmusters in die belegte EMS-Seite }
- for Offset:=0 to 16382 do
- Mem[Page_Frame_Base_Address:Offset]:=Offset mod 256;
-
- { und Prüfung }
- Writeln('Prüfung der EMS-Seite...');
-
- Offset:=1;
- Verify:=True;
- while (Offset<=16382) and (Verify=True) do
- begin
- if Mem[Page_Frame_Base_Address:Offset]<>Offset mod 256 then
- Verify:=False;
- Offset:=Succ(Offset);
- end; { while }
-
- if not Verify then
- begin
- Writeln('Fehler: Speicherung inkonsistent!!');
- Halt(1);
- end;
- Writeln('EMS-Speichertest fehlerfrei beendet.');
- Writeln;
-
- { Rückgabe der belegten Speicherseiten }
- Error_Code:=Deallocate_EM_Pages(Emm_Handle);
- if Error_Code<>STATUS_OK then
- Error('Fehler bei der Rückgabe belegter EMS-Seiten.', Error_Code);
- Writeln(APPLICATION_PAGE_COUNT, ' EMS-Seite(n) wieder freigegeben.');
- Writeln;
- Writeln('EMS-Testprogramm normal beendet.');
- end.