TP7 - allocation memory more than 512kB
Hi There!
Is possible allocate as a whole more than 512 Kb memory vin Turbo Pascal 7.0? I must make database to school and 512 kB is too little :(
thx for help
You would need to use either XMS or EMS memory for that. I'm not sure if this works on Windows NT (e.g. Windows 2000 and later). I have written two TP7 units (10+ years ago[smile]) that deal with this - let me now if you want to try them out. I would translate the comments to English then an post these here.
[edit]
I just tested it on Windows XP - XMS seems to work (at least up to 1MiB).
[/edit]
[edit]
I just tested it on Windows XP - XMS seems to work (at least up to 1MiB).
[/edit]
unit xms;{ THIS UNIT IS COPYRIGHT 1995,96 BY PATRICK LEVIN. IT'S FREE FOR USE AS LONG AS IT ISN'T COMMERCIAL.}interfaceconst ERR_NOERR = $00; { kein Fehler } ERR_NOTIMPLEMENTED = $80; { angegebene Funktion nicht bekannt } ERR_VDISKFOUND = $81; { VDISK-RAMDISK entdeckt } ERR_A20 = $82; { Fehler auf Adressleitung A20 } ERR_GENERAL = $8E; { allgemeiner Treiberfehler } ERR_UNRECOVERABLE = $8F; { nicht-behebbarer Fehler } ERR_HMANOTEXIST = $90; { keine HMA vorhanden } ERR_HMAINUSE = $91; { HMA bereits vergeben } ERR_HMAMINSIZE = $92; { zu wenig Platz in HMA } ERR_HMANOTALLOCED = $93; { HMA nicht allokiert } ERR_A20STILLON = $94; { Adressleitung A20 noch an } ERR_OUTOMEMORY = $A0; { kein extended Memory mehr frei } ERR_OUTOHANDLES = $A1; { alle XMS-Handles belegt } ERR_INVALIDHANDLE = $A2; { ungltiges Handle } ERR_SHINVALID = $A3; { Source-Handle ungltig } ERR_SOINVALID = $A4; { Source-Offset ungltig } ERR_DHINVALID = $A5; { Destination-Handle ungltig } ERR_DOINVALID = $A6; { Destination-Offset ungltig } ERR_LENINVALID = $A7; { ungltige L„nge fr Move- Funktion } ERR_OVERLAP = $A8; { verbotene šberlappung } ERR_PARITY = $A9; { Par„tits-Fehler } ERR_EMBUNLOCKED = $AA; { UMB ist nicht gesperrt } ERR_EMBLOCKED = $AB; { UMB ist noch gesperrt } ERR_LOCKOVERFLOW = $AC; { šberlauf des UMB-Sperrz„hlers } ERR_LOCKFAIL = $AD; { UMB kann nicht gesperrt werden } ERR_UMBSIZETOOBIG = $B0; { kleinerer UMB verfgbar } ERR_NOUMBS = $B1; { kein UMB mehr verfgbar } ERR_INVALIDUMB = $B2; { UMB-Segmentadresse ist ungltig }var XMS_Avail : boolean; SegXMM,OfsXMM : word; PtrXMM : pointer;const XMM_Error : integer = 0;function GetEMB (size: word): integer;procedure FreeEMB (Handle: integer);procedure ChangeEMBSize (Handle: integer;Newsize: word);procedure CopyMem (SourceHandle: integer;SourceOfs: longint; DestHandle: integer;DestOfs,Count: longint);function GetPhyAdr(segment,offset: word): longint;function GetHMA( LenB : word ) : boolean;procedure ReleaseHMA;function GetXMMErr: string; { (c) patrick levin }function FreeXMS: integer; { (c) patrick levin }implementation{ procedure Init ============== in : - out : XMM_Error, XMS_Avail, SegXMM, OfsXMM XMS_Avail=true, wenn XMS verfgbar XMM_Error h„lt Fehlerwert, wenn HIMEM.SYS nicht installiert Init stellt fest, ob ein XMM und XMS vorhanden sind und setzt einen Zeiger auf d. XMM}procedure Init;assembler;asm mov ax,4300h{ mov ax,$4300-> Fkt.nummer v. HIMEM.SYS ( Anmerkungen P.L. ) } int 2Fh { int 47 -> Multiplexeraufruf } cmp al,80h { -> HIMEM gibt als einziger 80h zurck (andere FFh)} je @Ok mov XMS_Avail,0 jmp @Ende@Ok: mov ax,4310h { mov ax,$4310 -> Fkt.nummer Adr. ermitteln } int 2Fh { Multiplexer aufrufen } mov SegXMM,es { Far Pointer als ES:BX } mov OfsXMM,bx mov XMS_Avail,1@Ende:end;{ Function GetEMB =============== in : Size out : Handle des EMB, XMM_Error Size gibt die Gr"áe des EMB in KByte an Handle ist das EMB-Handle f. die anderen Funktionen GetEMB allokiert Speicher im XMS}function GetEMB (size: word): integer;assembler;asm mov ah,9 { Fkt.nummer f. HIMEM } mov dx,size { Gr"áe in DX ablegen } call ds:[PtrXMM] { HIMEM ber Far Call aufrufen } cmp ax,1 { alles Ok ? } je @Ok mov bh,0 { nein, HiByte l"schen } mov XMM_Error,bx { Fehlerwert aus BX in XMM_Error laden } jmp @Ende { Ende }@Ok: mov XMM_Error,0 { kein Fehler } mov ax,dx { Handle in Ergebnisregister AX eintragen }@Ende:end;{ procedure FreeEMB ================= in : Handle out : XMM_Error Handle ist das, zuvor mit GetEMB ermittelte Handle d. EMB FreeEMB gibt allokierten Speicher wieder frei}procedure FreeEMB (Handle: integer);assembler;asm mov ah,$A { -> ah s„he leicht bescheuert aus } mov dx,Handle { Handle in DX laden } call ds:[PtrXMM] { HIMEM ber Far Call aufrufen } cmp ax,1 { alles Ok ? } je @Ende mov bh,0 { nein, Fehlerwert aus bx in XMM_Error laden } mov XMM_Error,bx@Ende:end;{ procedure ChangeEMBSize ======================= in : Handle,NewSize out : XMM_Error, Handle NewSize ist d. neue Gr"áe des bereits allokierten EMB ChangeEMBSize „ndert die Gr"áe allokierter EMBs}procedure ChangeEMBSize (Handle: integer;Newsize: word);assembler;asm mov ah,$F { Fkt.nummer f. HIMEM } mov bx,Newsize { Gr"áe nach BX laden } mov dx,Handle { Handle nach DX landen } call ds:[PtrXMM] { HIMEM ber Far Call } cmp ax,1 { alles Ok ? } je @Ok mov bh,0 { nein, Fehler aus BX } mov XMM_Error,bx jmp @Ende@Ok: mov XMM_Error,0 { Fehler auf null setzen} mov ax,dx { Handle aus DX nach AX }@Ende:end;{ procedure CopyMem ================= in : SourceHandle, SourceOfs, DestHandle, DestOfs, Count out : XMM_Error CopyMem kopiert den EMB m. SourceHandle und d. Adr. SourceOfs in den EMB m. DestHandle und der Adresse DestOfs}procedure CopyMem (SourceHandle: integer;SourceOfs: longint; DestHandle: integer;DestOfs,Count: longint);var SegXMMRec,OfsXMMRec: word; XMMRec: record Counter: longint; SrceHdl: integer; Source : longint; DestHdl: integer; Destina: longint; end;begin with XMMRec do begin Counter := Count; SrceHdl := SourceHandle; Source := SourceOfs; DestHdl := DestHandle; Destina := DestOfs; end; SegXMMRec := Seg(XMMRec); OfsXMMRec := Ofs(XMMRec); XMM_Error := 0; asm push ds mov ax,ds mov es,ax mov ax,SegXMMRec mov ds,ax mov si,OfsXMMRec mov ah,$b call es:[PtrXMM] cmp ax,1 je @Ende mov bh,0 mov SegXMMRec,bx@Ende: pop ds end; XMM_Error:=SegXMMRec;end;{ function GetHMA =============== in : Anzahl zu allokierender Bytes out : true, wenn HMA zur Verfgung gestellt wurde, sonst false TSR-Programme sollten nur genau den Speicher allokieren, den sie tat- s„chlich brauchen, andere $FFFF}function GetHMA( LenB : word ) : boolean; assembler; asm mov dx, lenB mov ah, 01h call ds:[PtrXMM] cmp ax,1 jne @Err mov XMM_Error,0 mov ax,00h jmp @Ende@Err: xor bh,bh mov XMM_Error,bx mov AX,01h@Ende:end;{ procedure ReleaseHMA ==================== in : - out : XMM_Error<>0, wenn HMA nicht allokiert wurde ReleaseHMA sollte vor Beendigung eines Programms, das die HMA benutzte, aufgerufen werden, damit nachfolgende Programme die HMA nut- zen k"nnen}procedure ReleaseHMA; assembler;asm mov ah,02h call ds:[PtrXMM] cmp bx,0 je @Ok xor bh,bh mov XMM_Error,bx jmp @TheEnd@Ok: mov XMM_Error,0@TheEnd:end;{ function GetXMMErr ================== in : - out : Fehlermeldungstring}function GetXMMErr: string;begin case XMM_Error of ERR_NOERR : GetXMMErr:='Kein Fehler.'; ERR_NOTIMPLEMENTED : GetXMMErr:='Unbekannte Funktion.'; ERR_VDISKFOUND : GetXMMErr:='VDISK - RAMDISK entdeckt.'; ERR_A20 : GetXMMErr:='Fehler auf A20 Adressleitung.'; ERR_GENERAL : GetXMMErr:='Allgemeiner Treiberfehler.'; ERR_UNRECOVERABLE : GetXMMErr:='Nicht-behebbarer Fehler.'; ERR_HMANOTEXIST : GetXMMErr:='Kein HMA gefunden.'; ERR_HMAINUSE : GetXMMErr:='HMA bereits vergeben.'; ERR_HMAMINSIZE : GetXMMErr:='Nicht genug Platz in HMA.'; ERR_HMANOTALLOCED : GetXMMErr:='HMA nicht allokiert.'; ERR_A20STILLON : GetXMMErr:='Adressleitung A20 ist noch aktiv.'; ERR_OUTOMEMORY : GetXMMErr:='Kein EMB verfgbar.'; ERR_OUTOHANDLES : GetXMMErr:='Kein Handle mehr verfgbar.'; ERR_INVALIDHANDLE : GetXMMErr:='Ungltiges Handle.'; ERR_SHINVALID : GetXMMErr:='Ungltiges Source-Handle.'; ERR_SOINVALID : GetXMMErr:='Ungltige Source-Adresse.'; ERR_DHINVALID : GetXMMErr:='Ungltiges Destination-Handle.'; ERR_DOINVALID : GetXMMErr:='Ungltige Destination-Adresse.'; ERR_LENINVALID : GetXMMErr:='Ungltige Anzahl von Bytes fr CopyMem.'; ERR_OVERLAP : GetXMMErr:='Verbotene šberlappung von Adressen.'; ERR_PARITY : GetXMMErr:='Parit„tsfehler.'; ERR_EMBUNLOCKED : GetXMMErr:='Nicht gesperrter UMB.'; ERR_EMBLOCKED : GetXMMErr:='UMB gesperrt.'; ERR_LOCKOVERFLOW : GetXMMErr:='UMB Sperrz„hler šberlauf.'; ERR_LOCKFAIL : GetXMMErr:='UMB kann nicht gesperrt werden.'; ERR_UMBSIZETOOBIG : GetXMMErr:='UMB zu groá.'; ERR_NOUMBS : GetXMMErr:='Kein UMB verfgbar.'; ERR_INVALIDUMB : GetXMMErr:='Ungltige UMB-Segmentadresse.'; else GetXMMErr:='Unbekannter Fehler.'; end;end;function FreeXMS: integer; assembler;asm mov ah,08h call ds:[PtrXMM] mov ax,dx cmp bx,80h jb @Ok xor bh,bh mov XMM_Error,bx jmp @TheEnd@Ok: mov XMM_Error,ERR_NOERR@TheEnd:end;function GetPhyAdr(segment,offset: word): longint;begin GetPhyAdr:=longint(segment) shl 16 or offset;end;{ Initialisierungsteil }begin Init; { XMS berprfen, Fehler setzen } PtrXMM:=Ptr(SegXMM,OfsXMM);{ Zeiger auf XMM initialisieren }end.
You can use the function GetEMB to allocate a memory block on XMS memory and use the returned handle with CopyMem to copy memory to and from this block. To convert a TP heap pointer to a longint handle, you just cast it:
{ from heap to xms }CopyMem( 0, longint(heapPtr), xmsHandle, xmsOffset, numberOfBytes );{ xms to heap }CopyMem( xmsHandle, xmsOffsetm, 0, longint(heapPtr), numberOfBytes );
HTH,
Pat.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement