/************************************************************************\ * File : XMS.cpp * ************************************************************************** * Fonctions de gestion de la m‚moire ‚tendue en C et ASM. * * * * Ecrit pour le Reporter no4 * * * * Copyright (c) 1994 J‚r“me Stolfo (UltimaN) * * * * Bas‚ sur le document : * * "eXtended Memory Specification (XMS), ver 3.00", by Microsoft(r), * * Lotus(r), Intel(r), AST(r) Research. * \************************************************************************/ #include "XMS.H" char XMSInitOK= 0; /* driver initialis‚ ? */ int XMSVerNum= 0; /* num‚ro de version */ unsigned char XMSErrorStat= 0; /* derniŠre erreur */ unsigned long XMSDriverAdress= 0; /* adresse du driver */ /********************************************/ /* Initialisation de la librairie et du */ /* driver. */ /* */ /* Parametres : aucun */ /* Retour : 1 succŠs */ /* 0 erreur (voir UXMSGetError()) */ /********************************************/ int XMSInit() { /* V‚rifie que le driver est pr‚sent */ asm { mov ax, 4300h int 2Fh cmp al,80h jne NoXMSDriver jmp XMSDriverOK } NoXMSDriver: /* pas de driver */ XMSErrorStat= 0x01; return 0; XMSDriverOK: /* driver pr‚sent */ asm { mov [XMSErrorStat],0 mov [XMSInitOK],1 /* R‚cupŠre l'adresse du driver */ mov ax,4310h int 2Fh mov word ptr [XMSDriverAdress],bx mov word ptr [XMSDriverAdress+2],es /* et r‚cupŠre le num‚ro de version du driver */ xor ah,ah // ah=0 call dword ptr [XMSDriverAdress] push bx and bh,00001111b add byte ptr [XMSVerNum+1],bh pop bx push bx and bh,11110000b shr bh,4 mov al,bh xor ah,ah mov bl,10 mul bl add byte ptr [XMSVerNum+1],al pop bx push bx and bl,00001111b add byte ptr [XMSVerNum], bl pop bx and bl,11110000b shr bl,4 mov al,bl xor ax,ax mov bl,10 mul bl add byte ptr [XMSVerNum], al } return 1; } /********************************************/ /* Retourne la derniŠre erreur */ /* */ /* ParamŠtres : aucun */ /* Retour : num‚ro de l'erreur (0: OK) */ /********************************************/ int XMSGetError() { return XMSErrorStat; } /********************************************/ /* Remet … 0 l'erreur aprŠs traitement */ /* */ /* ParamŠtres : aucun */ /* Retour : aucun */ /********************************************/ void XMSResetError() { XMSErrorStat=0; } /********************************************/ /* Retourne la version de driver XMS */ /* */ /* ParamŠtres : aucun */ /* Retour : int (hi byte : num‚ro :3) */ /* (lo byte : no de r‚v. :00)*/ /********************************************/ int XMSGetVersion() { return XMSVerNum; } /********************************************/ /* Retourne des informations sur la m‚moire */ /* libre. */ /* */ /* ParamŠtres : Retour : bloc le plus grand */ /* m‚moire libre */ /********************************************/ void XMSGetFreeMem( unsigned far *largest, unsigned far *free) { asm { push es mov ah,08h // Fonction 08h du driver call dword ptr [XMSDriverAdress] les di,[largest] // fait pointer es:di vers largest mov [word ptr es:di],ax les di,[free] // fait pointer es:di vers free mov [word ptr es:di],dx pop es } } /********************************************/ /* Alloue de la m‚moire ‚tendue */ /* */ /* ParamŠtres : taile du bloc en Ko */ /* retour : handle du bloc */ /* Retour : 1 succŠs */ /* 0 erreur */ /********************************************/ int XMSAllocate( unsigned length, unsigned far *handle) { asm { mov ah,09h // Fonction 09h mov dx,[length] call dword ptr [XMSDriverAdress] // Appelle le driver cmp ax,0 jz NotAllocated push es les di,[handle] mov [word ptr es:di],dx pop es } return 1; // OK NotAllocated: // Une erreur est survenue asm { mov [byte ptr XMSErrorStat],bl } return 0; } /********************************************/ /* R‚alloue de la m‚moire ‚tendue */ /* */ /* ParamŠtres : taille du bloc en Ko */ /* out: handle du bloc */ /* Retour : 1 succŠs */ /* 0 erreur */ /********************************************/ int XMSRealloc( unsigned size, unsigned handle) { asm { mov ah,0Fh // Fonction 0Fh mov bx,[size] mov dx,[handle] call dword ptr [XMSDriverAdress] // Appelle le driver cmp ax,0 jz NotReAllocated } return 1; NotReAllocated: // Erreur! asm { mov [byte ptr XMSErrorStat],bl } return 0; } /********************************************/ /* LibŠre un handle */ /* */ /* ParamŠtres : handle du bloc … lib‚rer */ /* Retour : 1 succŠs */ /* 0 erreur */ /********************************************/ int XMSFree( unsigned handle) { asm { mov ah,0Ah // Fonction 0Ah mov dx,[handle] call dword ptr [XMSDriverAdress] // Appelle le driver cmp ax,0 jz NotFreed } return 1; NotFreed: // Erreur ! asm mov [XMSErrorStat],bl return 0; } /********************************************/ /* TransfŠre un bloc (XMS<->XMS ou XMS<->RAM*/ /* */ /* ParamŠtres : structure XMSMoveStruct */ /* Retour : 1 succŠs */ /* 0 erreur */ /********************************************/ int XMSMove( struct XMSMoveStruct far *str) { asm { push es push ds pop es push ds // Empile 'es' et 'ds', et donne la valeur de 'ds' … 'es' mov ah,0Bh // Fonction 0Bh lds si,[str] // Fait pointer ds:si sur str call dword ptr es:[XMSDriverAdress] // Appelle le driver cmp ax,0 jz NotMoved pop ds pop es } return 1; NotMoved: // Erreur ! asm mov [XMSErrorStat],bl; return 0; } /********************************************/ /* Verrouille un bloc en XMS (pour qu'il */ /* ne bouge pas) */ /* */ /* ParamŠtres: handle … v‚rouiller */ /* out: adresse 32-bit du bloc */ /* Retour : 1 succŠs */ /* 0 erreur */ /********************************************/ int XMSLock( unsigned handle, void far *addr) { asm { mov ah, 0Ch // Fonction 0Ch mov dx, [handle] call dword ptr [XMSDriverAdress] // Appelle le driver push es // Sauvegarde es les di,[addr] // pointe es:di vers addr mov [word ptr es:di],bx // stocke l'offset mov [word ptr es:di+2],dx // puis le segment pop es // Restaure es cmp ax, 0 jz NotOK } return 1; NotOK: // Erreur ! asm mov [XMSErrorStat],bl return 0; } /********************************************/ /* D‚verouille le bloc */ /* */ /* ParamŠtres : handle ud bloc … d‚verrouil.*/ /* Retour : 1 succŠs */ /* 0 erreur */ /********************************************/ int XMSUnlock( unsigned handle) { asm { mov ah,0Dh // Fonction 0Dh mov dx,[handle] call dword ptr [XMSDriverAdress] // Appelle l'adresse cmp ax,0 jz AnError } return 1; AnError: // Erreur ! asm mov [XMSErrorStat],bl return 0; } /********************************************/ /* Retourne des infos sur un bloc */ /* */ /* ParamŠtres : handle … inspecter */ /* retour : verrouillage */ /* Nb de handle libres */ /* Taille du bloc en Ko */ /* Retour : 1 succŠs */ /* 0 erreur */ /********************************************/ int XMSGetInfo( unsigned handle, unsigned char far *count, unsigned char far *free, unsigned far *len) { asm { mov ah,0Eh // Fonction 0Eh mov dx,[handle] call [XMSDriverAdress] // Appelle le driver push es // Sauvegarde es, pui les di,[count] // remplit count, free, et len mov [byte ptr es:di],bh les di,[free] mov [byte ptr es:di],bl les di,[len] mov [word ptr es:di],dx pop es // et restaure es cmp ax,0 jz NoInfo } return 1; NoInfo: // Erreur ! asm mov [XMSErrorStat],bl return 0; }