CD_OUT_SRC/XMSSUPP.CPP
2021-09-03 17:50:32 +02:00

940 lines
26 KiB
C++
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <stdio.h>
#include <conio.h>
#include <dos.h>
#include <malloc.h>
#include <string.h>
#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;
}
}