940 lines
26 KiB
C++
940 lines
26 KiB
C++
#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;
|
||
}
|
||
}
|