#include #include #include #include #include #include "XMSSUPP.H" // extern unsigned _stklen = 16000U; /* XmsSupp::XmsSupp() //////////////////////////////////////////////////////////////////////////// // Descripcion: Constructor de Clase. // // Entradas: Ninguna. // // Salidas: Ninguna. //////////////////////////////////////////////////////////////////////////// { lError=0; // Indicador de Error a cero InitXms(); // Inicializa XMS. } void XmsSupp::InitXms() //////////////////////////////////////////////////////////////////////////// // Descripcion: Inicializa la Clase. // // Entradas: Ninguna. // // Salidas: 1 Controlador XMS Presente. // 0 Controlador XMS Ausente. //////////////////////////////////////////////////////////////////////////// { char Stat; _asm{ mov ax,0x04300; int 0x02f; // Mira si esta el Driver mov Stat,al; // Guarda valor en Stat } if(Stat==(char)0x80) // ¨ Stat=80H ? { Present=1; // Si, Esta presente GetXmsDir(); // Donde esta el driver. GetXmsVer(); // Mira version GetXmsFree(); // Mira memoria libre GetInfo(); // Informe de estado. } else { Present=0; // Si no, no presente GetXmsErr(0xFF); // Pon error. } } void XmsSupp::GetInfo() //////////////////////////////////////////////////////////////////////////// // Descripcion: Captura Informacion de la XMS. // // Entradas: Ninguna. // // Salidas: Ninguna. //////////////////////////////////////////////////////////////////////////// { printf("ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿\n"); printf("³ Soporte XMS V 1.0. Fernando Perez Alonso. '95 ³\n"); printf("³ ³\n"); printf("³ Ver. XMS. %o.%02o.\t\t\t\t ³\n",HiVerXms,LoVerXms); printf("³ Rev. XMS. %o.%02o.\t\t\t\t ³\n",HiVerCtr,LoVerCtr); if(lHMA) printf("³ HMA Presente. ³\n"); else printf("³ HMA Ausente. ³\n"); printf("³ Memoria Libre %4u Ks.\t\t\t ³\n",TotXmsFree); printf("³ Tama¤o Max. Bloque %4u Ks.\t\t\t ³\n",BigBlock); printf("ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ\n\n\n"); } void XmsSupp::GetXmsDir() { //////////////////////////////////////////////////////////////////////////// // Descripcion: Captura la Direccion del Contolador de XMS. // // Entradas: Ninguna. // // Salidas: Ninguna. //////////////////////////////////////////////////////////////////////////// unsigned long XMSDIR; if(!Present) // No Esta presente ? { GetXmsErr(0xFF); // Pon error return; // y retorna. } _asm{ push es; // guarda ES en la pila mov ax,0x04310; // capturamos direccion int 0x02f; // del driver mov word ptr XMSDIR,bx // y la guardamos mov word ptr XMSDIR+2,es // en la varibale XMSDIR pop es; // recupera ES } XmsDir=XMSDIR; // actualiza la varibale de clase. return; } void XmsSupp::GetXmsVer() //////////////////////////////////////////////////////////////////////////// // Descripcion: Captura Version, Revision y estado del HMA. // // Entradas: Ninguna. // // Salidas: Ninguna. //////////////////////////////////////////////////////////////////////////// { unsigned long XMSDIR=XmsDir; char HVXMS,LVXMS,HVCTR,LVCTR; unsigned HMA; if(!Present) { GetXmsErr(0xFF); return; } _asm{ mov ah,0; // Miraremos call dword ptr XMSDIR; // Informacion del driver mov HVXMS,ah; // Version mov LVXMS,al; // mov HVCTR,bh; // Revision mov LVCTR,bl; // mov HMA,dx; // Estado del HMA } HiVerXms=HVXMS; // Actualizamos HiVerCtr=HVCTR; // variables LoVerXms=LVXMS; // de LoVerCtr=LVCTR; // Clase lHMA=HMA; // } void XmsSupp::GetXmsFree() //////////////////////////////////////////////////////////////////////////// // Descripcion: Captura Memoria XMS Libre. // // Entradas: Ninguna. // // Salidas: Ninguna. //////////////////////////////////////////////////////////////////////////// { unsigned long XMSDIR=XmsDir; unsigned BIGBLOCK; unsigned TOTXMSFREE; if(!Present) { GetXmsErr(0xFF); return; } _asm{ mov ah,8; // Campturamos memoria call dword ptr XMSDIR; // Libre mov BIGBLOCK,ax; // y el tama¤o mov TOTXMSFREE,dx; // del bloque mas grande } BigBlock=BIGBLOCK; // Actualizamos TotXmsFree=TOTXMSFREE; // variables de clase } void XmsSupp::SetConPntr(void far *Puntero) //////////////////////////////////////////////////////////////////////////// // Descripcion: Actualiza la Zona de Descarga en Memoria Convencional. // // Entradas: Puntero a Bloque de Control XMS. // Puntero a Memoria reservada en Convencional. // // Salidas: Ninguna. //////////////////////////////////////////////////////////////////////////// { unsigned long Desp; unsigned Segm =FP_SEG(Puntero); unsigned Offst=FP_OFF(Puntero); _asm{ mov ax,Offst; // Actualiza el mov word ptr Desp,ax; // Puntero de Origen mov ax,Segm; // en la estructura mov word ptr Desp+2,ax; // XMSBlock } ThisXMSBlock.SrcDesp =Desp; // Varble de clase } void XmsSupp::AllocXms(unsigned KLen) //////////////////////////////////////////////////////////////////////////// // Descripcion: Reserva memoria XMS. // // Entradas: Longitud de memoria a reservar en Kilo Bytes. // Puntero a Bloque de Control XMS. // // Salidas: Ninguna. //////////////////////////////////////////////////////////////////////////// { unsigned long XMSDIR=XmsDir; unsigned handle; unsigned err; char cerr; if(!Present) { GetXmsErr(0xFF); return; } _asm{ mov ah,9; // reserva memoria mov dx,KLen; // extendida call dword ptr XMSDIR; mov err,ax; // AX=error mov cerr,bl; // BL=Codigo de error mov handle,dx; // Hadle de bloque de memo. } ThisXMSBlock.Len =KLen*1024L; // Actualiza variables de ThisXMSBlock.DstHandle=handle; // la clase ThisXMSBlock.SrcHandle=0; ThisXMSBlock.DstDesp =0L; if(err!=1) // si hay error { GetXmsErr(cerr); // mira cuales Reserved=0; // Reservada = falso } else Reserved=1; // sino, reservada = cierto } void XmsSupp::FreeXms() //////////////////////////////////////////////////////////////////////////// // Descripcion: Libera memoria XMS. // // Entradas: Bloque de Control XMS. // // Salidas: Ninguna. //////////////////////////////////////////////////////////////////////////// { unsigned long XMSDIR=XmsDir; unsigned handle; unsigned err; char cerr; if(!Present) { GetXmsErr(0xFF); return; } if(!Reserved) { GetXmsErr(0xFE); return; } handle=ThisXMSBlock.DstHandle; _asm{ mov ah,10; // Libera memoria mov dx,handle; // extendida call dword ptr XMSDIR; mov err,ax; // y comprueba errores mov cerr,bl; } if(err!=1) GetXmsErr(cerr); } void XmsSupp::Move2Xms() //////////////////////////////////////////////////////////////////////////// // Descripcion: Mueve un Bloque de Memoria Convencional a XMS. // // Entradas: Bloque de Control XMS. // // Salidas: Ninguna. //////////////////////////////////////////////////////////////////////////// { unsigned long XMSDIR=XmsDir; unsigned err; char cerr; unsigned Segment=FP_SEG(&ThisXMSBlock); // Segmento y unsigned Offst =FP_OFF(&ThisXMSBlock); // Offset de la estructura XMSBlock if(!Present) { GetXmsErr(0xFF); return; } if(!Reserved) { GetXmsErr(0xFE); return; } _asm{ push ds; // Guarda registros en push si; // la pila mov ax,Segment; // carga en ds:si la mov ds,ax; // la direccion de mov si,Offst; // la estructura mov ah,0bh; // y mueve el bloque de call dword ptr XMSDIR; // memoria de Convencional mov err,ax; // a XMS mov cerr,bl; // mira si hay errores pop si; // Recupera registros pop ds; } if(err!=1) GetXmsErr(cerr); } void XmsSupp::Move2Con() //////////////////////////////////////////////////////////////////////////// // Descripcion: Mueve un Bloque de Memoria XMS a Convencional. // // Entradas: Bloque de Control XMS. // // Salidas: Ninguna. //////////////////////////////////////////////////////////////////////////// { unsigned long XMSDIR=XmsDir; unsigned err; char cerr; unsigned long wDesp; unsigned wHand; unsigned Segment=FP_SEG(&ThisXMSBlock); unsigned Offst =FP_OFF(&ThisXMSBlock); if(!Present) { GetXmsErr(0xFF); return; } if(!Reserved) { GetXmsErr(0xFE); return; } wDesp=ThisXMSBlock.SrcDesp; // Intercambia valores de wHand=ThisXMSBlock.SrcHandle; // Origen y ThisXMSBlock.SrcDesp =ThisXMSBlock.DstDesp; // Destino ThisXMSBlock.SrcHandle=ThisXMSBlock.DstHandle; ThisXMSBlock.DstDesp =wDesp; ThisXMSBlock.DstHandle=wHand; _asm{ push ds; push si; mov ax,Segment; mov ds,ax; mov si,Offst; // Mueve de Xms a mov ah,0bh; // convencional call dword ptr XMSDIR; mov err,ax; // mira si hay errores mov cerr,bl; pop si; pop ds; } if(err!=1) GetXmsErr(cerr); } void XmsSupp::GetXmsErr(char error) //////////////////////////////////////////////////////////////////////////// // Descripcion: Actualiza la Variable de Clase cError. // // Entradas: Codigo de Error. // // Salidas: Ninguna. //////////////////////////////////////////////////////////////////////////// { char *SysErr; lError=1; switch(error) { case 0x80: strcpy(cError,"Funci¢n no implemetada."); break; case 0x81: strcpy(cError,"VDISK Detectado."); break; case 0x82: strcpy(cError,"Error en l¡nea A20."); break; case 0x8e: strcpy(cError,"Error general de controlador."); break; case 0x8f: strcpy(cError,"Error irrecuperable."); break; case 0x90: strcpy(cError,"HMA no existe ."); break; case 0x91: strcpy(cError,"HMA en uso."); break; case 0x92: strcpy(cError,"DX menor al par metro /HMAMIN."); break; case 0x93: strcpy(cError,"HMA no asignado."); break; case 0x94: strcpy(cError,"L¡nea A20 activa."); break; case 0xa0: strcpy(cError,"No hay suficente memoria libre."); break; case 0xa1: strcpy(cError,"Handles XMS agotados."); break; case 0xa2: strcpy(cError,"Handle no v lido."); break; case 0xa3: strcpy(cError,"Handle fuente no v lido."); break; case 0xa4: strcpy(cError,"Offset fuente no v lido."); break; case 0xa5: strcpy(cError,"Handle destino no v lido."); break; case 0xa6: strcpy(cError,"Offset destino no v lido."); break; case 0xa7: strcpy(cError,"Tama¤o para MOVE no v lido ."); break; case 0xa8: strcpy(cError,"Se ha producido Solapamiento en la funci¢n MOVE."); break; case 0xa9: strcpy(cError,"Se detecto error de paridad."); break; case 0xaa: strcpy(cError,"No se bloqueo el EMB ."); break; case 0xab: strcpy(cError,"EMB ya bloqueado."); break; case 0xac: strcpy(cError,"Bloqueo por desbordamiento del contador."); break; case 0xad: strcpy(cError,"No se bloqueo el EMB."); break; case 0xFE: strcpy(cError,"No se Reservo Memoria XMS."); break; case 0xFF: strcpy(cError,"Controlador XMS ausente."); break; default: strcpy(cError,"OK."); break; } } */ void Init_Xms(XmsSupp *XmsBlock) //////////////////////////////////////////////////////////////////////////// // Descripcion: Constructor de Clase. // // Entradas: Ninguna. // // Salidas: Ninguna. //////////////////////////////////////////////////////////////////////////// { XmsBlock ->lError=0; // Indicador de Error a cero InitXms(XmsBlock); // Inicializa XMS. } void InitXms(XmsSupp *XmsBlock) //////////////////////////////////////////////////////////////////////////// // Descripcion: Inicializa la Clase. // // Entradas: Ninguna. // // Salidas: 1 Controlador XMS Presente. // 0 Controlador XMS Ausente. //////////////////////////////////////////////////////////////////////////// { char Stat; _asm{ // mov ax,0x4300; mov ax,4300h; int 0x2f; // Mira si esta el Driver mov Stat,al; // Guarda valor en Stat } if(Stat==(char)0x80) // ¨ Stat=80H ? { XmsBlock -> Present=1; // Si, Esta presente GetXmsDir(XmsBlock); // Donde esta el driver. GetXmsVer(XmsBlock); // Mira version GetXmsFree(XmsBlock); // Mira memoria libre } else { XmsBlock -> Present=0; // Si no, no presente GetXmsErr(0xFF, XmsBlock ); // Pon error. } } void GetInfo(XmsSupp *XmsBlock) //////////////////////////////////////////////////////////////////////////// // Descripcion: Captura Informacion de la XMS. // // Entradas: Ninguna. // // Salidas: Ninguna. //////////////////////////////////////////////////////////////////////////// { printf("ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿\n"); printf("³ ³\n"); printf("³ Ver. XMS. %o.%02o.\t\t\t\t ³\n",XmsBlock->HiVerXms,XmsBlock->LoVerXms); printf("³ Rev. XMS. %o.%02o.\t\t\t\t ³\n",XmsBlock->HiVerCtr,XmsBlock->LoVerCtr); if(XmsBlock->lHMA) printf("³ HMA Presente. ³\n"); else printf("³ HMA Ausente. ³\n"); printf("³ Memoria Libre %4u Ks.\t\t\t ³\n",XmsBlock->TotXmsFree); printf("³ Tama¤o Max. Bloque %4u Ks.\t\t\t ³\n",XmsBlock->BigBlock); printf("ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ\n\n\n"); } void GetXmsDir(XmsSupp *XmsBlock) { //////////////////////////////////////////////////////////////////////////// // Descripcion: Captura la Direccion del Contolador de XMS. // // Entradas: Ninguna. // // Salidas: Ninguna. //////////////////////////////////////////////////////////////////////////// unsigned long XMSDIR; if(!XmsBlock->Present) // No Esta presente ? { GetXmsErr(0xFF, XmsBlock ); // Pon error return; // y retorna. } _asm{ push es; // guarda ES en la pila // mov ax,0x4310; // capturamos direccion mov ax,4310h; // capturamos direccion int 2fh; // del driver // int 0x2f; // del driver mov word ptr XMSDIR,bx // y la guardamos mov word ptr XMSDIR+2,es // en la varibale XMSDIR ////////// // xor ax,ax; // call word ptr XMSDIR; ////////// pop es; // recupera ES } XmsBlock -> XmsDir=XMSDIR; // actualiza la varibale de clase. return; } void GetXmsVer(XmsSupp *XmsBlock) //////////////////////////////////////////////////////////////////////////// // Descripcion: Captura Version, Revision y estado del HMA. // // Entradas: Ninguna. // // Salidas: Ninguna. //////////////////////////////////////////////////////////////////////////// { unsigned long XMSDIR=XmsBlock ->XmsDir; char HVXMS,LVXMS,HVCTR,LVCTR; unsigned HMA; if(!XmsBlock->Present) { GetXmsErr(0xFF, XmsBlock); return; } _asm{ mov ah,0; // Miraremos call dword ptr XMSDIR; // Informacion del driver mov HVXMS,ah; // Version mov LVXMS,al; // mov HVCTR,bh; // Revision mov LVCTR,bl; // mov HMA,dx; // Estado del HMA } XmsBlock ->HiVerXms=HVXMS; // Actualizamos XmsBlock ->HiVerCtr=HVCTR; // variables XmsBlock ->LoVerXms=LVXMS; // de XmsBlock ->LoVerCtr=LVCTR; // Clase XmsBlock ->lHMA=HMA; // } void GetXmsFree(XmsSupp *XmsBlock) //////////////////////////////////////////////////////////////////////////// // Descripcion: Captura Memoria XMS Libre. // // Entradas: Ninguna. // // Salidas: Ninguna. //////////////////////////////////////////////////////////////////////////// { unsigned long XMSDIR=XmsBlock ->XmsDir; unsigned BIGBLOCK; unsigned TOTXMSFREE; if(!XmsBlock->Present) { GetXmsErr(0xFF, XmsBlock); return; } _asm{ mov ah,8; // Campturamos memoria call dword ptr XMSDIR; // Libre mov BIGBLOCK,ax; // y el tama¤o mov TOTXMSFREE,dx; // del bloque mas grande } XmsBlock ->BigBlock=BIGBLOCK; // Actualizamos XmsBlock ->TotXmsFree=TOTXMSFREE; // variables de clase } void SetConPntr(void far *Puntero, XmsSupp *XmsBlock) //////////////////////////////////////////////////////////////////////////// // Descripcion: Actualiza la Zona de Descarga en Memoria Convencional. // // Entradas: Puntero a Bloque de Control XMS. // Puntero a Memoria reservada en Convencional. // // Salidas: Ninguna. //////////////////////////////////////////////////////////////////////////// { unsigned long Desp; unsigned Segm =FP_SEG(Puntero); unsigned Offst=FP_OFF(Puntero); _asm{ mov ax,Offst; // Actualiza el mov word ptr Desp,ax; // Puntero de Origen mov ax,Segm; // en la estructura mov word ptr Desp+2,ax; // XMSBlock } XmsBlock ->ThisXMSBlock.SrcDesp = Desp; // Varble de clase } void AllocXms(unsigned KLen, XmsSupp *XmsBlock) //////////////////////////////////////////////////////////////////////////// // Descripcion: Reserva memoria XMS. // // Entradas: Longitud de memoria a reservar en Kilo Bytes. // Puntero a Bloque de Control XMS. // // Salidas: Ninguna. //////////////////////////////////////////////////////////////////////////// { unsigned long XMSDIR=XmsBlock ->XmsDir; unsigned handle; unsigned err; char cerr; if(!XmsBlock->Present) { GetXmsErr(0xFF, XmsBlock); return; } _asm{ mov ah,9; // reserva memoria mov dx,KLen; // extendida call dword ptr XMSDIR; mov err,ax; // AX=error // mov cerr,bl; // BL=Codigo de error mov handle,dx; // Hadle de bloque de memo. mov cerr,bl; // BL=Codigo de error } XmsBlock ->ThisXMSBlock.Len =KLen*1024L; // Actualiza variables de XmsBlock ->ThisXMSBlock.DstHandle=handle; // la clase XmsBlock ->ThisXMSBlock.SrcHandle=0; XmsBlock ->ThisXMSBlock.DstDesp =0L; if(err!=1) // si hay error { GetXmsErr(cerr, XmsBlock); // mira cuales XmsBlock ->Reserved=0; // Reservada = falso } else XmsBlock ->Reserved=1; // sino, reservada = cierto } void FreeXms(XmsSupp *XmsBlock) //////////////////////////////////////////////////////////////////////////// // Descripcion: Libera memoria XMS. // // Entradas: Bloque de Control XMS. // // Salidas: Ninguna. /////////////////////////////////////////////////////////////////////////// { unsigned long XMSDIR=XmsBlock ->XmsDir; unsigned handle; unsigned err; char cerr; if(!XmsBlock->Present) { GetXmsErr(0xFF, XmsBlock); return; } if(!XmsBlock ->Reserved) { GetXmsErr(0xFE, XmsBlock); return; } handle=XmsBlock ->ThisXMSBlock.DstHandle; _asm{ // mov ah,10; // Libera memoria mov dx,handle; // extendida mov ah,10; // Libera memoria // mov dx,handle; // extendida call dword ptr XMSDIR; mov err,ax; // y comprueba errores mov cerr,bl; } if(err!=1) GetXmsErr(cerr, XmsBlock); } void Move2Xms(XmsSupp *XmsBlock) //////////////////////////////////////////////////////////////////////////// // Descripcion: Mueve un Bloque de Memoria Convencional a XMS. // // Entradas: Bloque de Control XMS. // // Salidas: Ninguna. //////////////////////////////////////////////////////////////////////////// { unsigned long XMSDIR=XmsBlock ->XmsDir; unsigned err; char cerr; //unsigned Segment=FP_SEG(XmsBlock ->&ThisXMSBlock); // Segmento y //unsigned Offst =FP_OFF(XmsBlock ->&ThisXMSBlock); // Offset de la estructura XMSBlock unsigned Segment=FP_SEG(&(XmsBlock ->ThisXMSBlock)); // Segmento y unsigned Offst =FP_OFF(&(XmsBlock ->ThisXMSBlock)); // Offset de la estructura XMSBlock if(!XmsBlock->Present) { GetXmsErr(0xFF, XmsBlock); return; } if(!XmsBlock ->Reserved) { GetXmsErr(0xFE, XmsBlock); return; } _asm{ push ds; // Guarda registros en push si; // la pila mov ax,Segment; // carga en ds:si la mov ds,ax; // la direccion de mov si,Offst; // la estructura mov ah,0bh; // y mueve el bloque de call dword ptr XMSDIR; // memoria de Convencional mov err,ax; // a XMS mov cerr,bl; // mira si hay errores pop si; // Recupera registros pop ds; } if(err!=1) GetXmsErr(cerr, XmsBlock); } void Move2Con(XmsSupp *XmsBlock) //////////////////////////////////////////////////////////////////////////// // Descripcion: Mueve un Bloque de Memoria XMS a Convencional. // // Entradas: Bloque de Control XMS. // // Salidas: Ninguna. //////////////////////////////////////////////////////////////////////////// { unsigned long XMSDIR=XmsBlock ->XmsDir; unsigned err; char cerr; unsigned long wDesp; unsigned wHand; //unsigned Segment=FP_SEG(XmsBlock ->&ThisXMSBlock); //unsigned Offst =FP_OFF(XmsBlock ->&ThisXMSBlock); unsigned Segment=FP_SEG(&(XmsBlock ->ThisXMSBlock)); unsigned Offst =FP_OFF(&(XmsBlock ->ThisXMSBlock)); if(!XmsBlock->Present) { GetXmsErr(0xFF, XmsBlock); return; } if(!XmsBlock->Reserved) { GetXmsErr(0xFE, XmsBlock); return; } wDesp=XmsBlock ->ThisXMSBlock.SrcDesp; // Intercambia valores de wHand=XmsBlock ->ThisXMSBlock.SrcHandle; // Origen y XmsBlock ->ThisXMSBlock.SrcDesp =XmsBlock ->ThisXMSBlock.DstDesp; // Destino XmsBlock ->ThisXMSBlock.SrcHandle=XmsBlock ->ThisXMSBlock.DstHandle; XmsBlock ->ThisXMSBlock.DstDesp =wDesp; XmsBlock ->ThisXMSBlock.DstHandle=wHand; _asm{ push ds; push si; mov ax,Segment; mov ds,ax; mov si,Offst; // Mueve de Xms a mov ah,0bh; // convencional call dword ptr XMSDIR; mov err,ax; // mira si hay errores mov cerr,bl; pop si; pop ds; } if(err!=1) GetXmsErr(cerr, XmsBlock); // Devuelve valores a su origen wDesp=XmsBlock ->ThisXMSBlock.DstDesp; // Intercambia valores de wHand=XmsBlock ->ThisXMSBlock.DstHandle; // Origen y XmsBlock ->ThisXMSBlock.DstDesp = XmsBlock ->ThisXMSBlock.SrcDesp; // Destino XmsBlock ->ThisXMSBlock.DstHandle = XmsBlock ->ThisXMSBlock.SrcHandle; XmsBlock ->ThisXMSBlock.SrcDesp =wDesp; XmsBlock ->ThisXMSBlock.SrcHandle=wHand; } void GetXmsErr(char error,XmsSupp *XmsBlock) //////////////////////////////////////////////////////////////////////////// // Descripcion: Actualiza la Variable de Clase cError. // // Entradas: Codigo de Error. // // Salidas: Ninguna. //////////////////////////////////////////////////////////////////////////// { char *SysErr; XmsBlock ->lError=1; switch(error) { case 0x80: strcpy(XmsBlock ->cError,"Funci¢n no implemetada."); break; case 0x81: strcpy(XmsBlock ->cError,"VDISK Detectado."); break; case 0x82: strcpy(XmsBlock ->cError,"Error en l¡nea A20."); break; case 0x8e: strcpy(XmsBlock ->cError,"Error general de controlador."); break; case 0x8f: strcpy(XmsBlock ->cError,"Error irrecuperable."); break; case 0x90: strcpy(XmsBlock ->cError,"HMA no existe ."); break; case 0x91: strcpy(XmsBlock ->cError,"HMA en uso."); break; case 0x92: strcpy(XmsBlock ->cError,"DX menor al par metro /HMAMIN."); break; case 0x93: strcpy(XmsBlock ->cError,"HMA no asignado."); break; case 0x94: strcpy(XmsBlock ->cError,"L¡nea A20 activa."); break; case 0xa0: strcpy(XmsBlock ->cError,"No hay suficente memoria libre."); break; case 0xa1: strcpy(XmsBlock ->cError,"Handles XMS agotados."); break; case 0xa2: strcpy(XmsBlock ->cError,"Handle no v lido."); break; case 0xa3: strcpy(XmsBlock ->cError,"Handle fuente no v lido."); break; case 0xa4: strcpy(XmsBlock ->cError,"Offset fuente no v lido."); break; case 0xa5: strcpy(XmsBlock ->cError,"Handle destino no v lido."); break; case 0xa6: strcpy(XmsBlock ->cError,"Offset destino no v lido."); break; case 0xa7: strcpy(XmsBlock ->cError,"Tama¤o para MOVE no v lido ."); break; case 0xa8: strcpy(XmsBlock ->cError,"Se ha producido Solapamiento en la funci¢n MOVE."); break; case 0xa9: strcpy(XmsBlock ->cError,"Se detecto error de paridad."); break; case 0xaa: strcpy(XmsBlock ->cError,"No se bloqueo el EMB ."); break; case 0xab: strcpy(XmsBlock ->cError,"EMB ya bloqueado."); break; case 0xac: strcpy(XmsBlock ->cError,"Bloqueo por desbordamiento del contador."); break; case 0xad: strcpy(XmsBlock ->cError,"No se bloqueo el EMB."); break; case 0xFE: strcpy(XmsBlock ->cError,"No se Reservo Memoria XMS."); break; case 0xFF: strcpy(XmsBlock ->cError,"Controlador XMS ausente."); break; default: unsigned int value = error; sprintf(XmsBlock ->cError,"OK. %X %u", value, value); // strcpy(XmsBlock ->cError,"OK."); break; } }