First commit 09/04/1995
This commit is contained in:
402
EMMC.CPP
Normal file
402
EMMC.CPP
Normal file
@ -0,0 +1,402 @@
|
||||
/**********************************************************************/
|
||||
/* E M M C */
|
||||
/*--------------------------------------------------------------------*/
|
||||
/* Tarea : contiene algunas funciones para acceder a la */
|
||||
/* memoria EMS (Expanded Memory) */
|
||||
/*--------------------------------------------------------------------*/
|
||||
/* Autor : MICHAEL TISCHER */
|
||||
/* desarrollado el: 30.08.1988 */
|
||||
/* <20>ltimo update : 29.01.1995 */
|
||||
/*--------------------------------------------------------------------*/
|
||||
/* modelo de memoria: alguno con puntero FAR a los datos, es */
|
||||
/* decir Compact, Large o Huge */
|
||||
/**********************************************************************/
|
||||
|
||||
/*== enlazar archivos Include =======================================*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <conio.h>
|
||||
#include <dos.h>
|
||||
#include "EMMC.h"
|
||||
|
||||
/*== Typedefs ========================================================*/
|
||||
|
||||
typedef unsigned char BYTE; /*nos construimos un byte*/
|
||||
typedef unsigned int WORD;
|
||||
typedef BYTE BOOL; /*como BOOLEAN en Pascal*/
|
||||
|
||||
/*== Macros ==========================================================*/
|
||||
|
||||
/*-- MK_FP crea de una direcci<63>n de segmento y Offset un -------------*/
|
||||
/*-- puntero FAR a un objeto -------*/
|
||||
|
||||
#ifdef MK_FP /*<2A>ya se defini<6E> MK_FP?*/
|
||||
#undef MK_FP
|
||||
#endif
|
||||
#define MK_FP(seg, ofs) ((void far *) ((unsigned long) (seg)<<16|(ofs)))
|
||||
|
||||
/*-- PAGE_ADR devuelve un puntero a la p<>gina f<>sica X dentro del ----*/
|
||||
/*-- Page-Frame de la memoria EMS ----*/
|
||||
|
||||
#define PAGE_ADR(x) ((void *) MK_FP(ems_frame_seg() + ((x) << 10), 0))
|
||||
|
||||
/*== Constantes ======================================================*/
|
||||
|
||||
#define TRUE 1 /*Constantes para el trabajo con BOOL*/
|
||||
#define FALSE 0
|
||||
|
||||
#define EMS_INT 0x67 /*n<>mero de interrupci<63>n para acceder a la EMM*/
|
||||
#define EMS_ERR -1 /*se devuelve en caso de error*/
|
||||
|
||||
/*== variables globales===============================================*/
|
||||
|
||||
BYTE emm_ec; /*aqu<71> se guardan los c<>digos de error EMM*/
|
||||
|
||||
/***********************************************************************/
|
||||
/* Funci<63>n : E M S _ I N S T */
|
||||
/**--------------------------------------------------------------------**/
|
||||
/* Tarea : Determina si hay instalada memoria EMS, y un */
|
||||
/* driver EMS (EMM) asociado. */
|
||||
/* Par<61>metro entrada: ninguno */
|
||||
/* Valor de retorno : TRUE, si hay memoria EMS instalada, sino */
|
||||
/* FALSE. */
|
||||
/************************************************************************/
|
||||
|
||||
BOOL ems_inst()
|
||||
{
|
||||
static char emm_name[] = { 'E', 'M', 'M', 'X', 'X', 'X', 'X', '0' };
|
||||
union REGS regs; /*reg. de proc. para la llamada de interr.*/
|
||||
struct SREGS sregs; /*reg. de segm. para la llamada de interr.*/
|
||||
|
||||
/*-- Construir puntero a nombre en cabecera de un contr. de disp. --*/
|
||||
|
||||
regs.x.ax = 0x3567; /*n<> de func.: obtener vector int. 0x67*/
|
||||
intdosx(®s, ®s, &sregs); /*llamar la interr. del DOS 0x21*/
|
||||
return !memcmp( MK_FP(sregs.es, 10), emm_name, sizeof emm_name );
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* Funci<63>n : E M S _ N U M _ P A G E */
|
||||
/**--------------------------------------------------------------------**/
|
||||
/* Tarea : Obtiene el n<> total de p<>ginas EMS. */
|
||||
/* Par<61>metro entrada: ninguno */
|
||||
/* Valor de retorno : EMS_ERR en caso de error, sino el n<>mero de */
|
||||
/* p<>ginas EMS. */
|
||||
/************************************************************************/
|
||||
int ems_num_page()
|
||||
{
|
||||
union REGS regs; /*reg. de proc. para la llamada de interr.*/
|
||||
|
||||
regs.h.ah = 0x42; /*n<>mero de funci<63>n: obtener n<>mero de p<>ginas*/
|
||||
int86(EMS_INT, ®s, ®s); /*llamar EMM*/
|
||||
if ((int) (emm_ec = regs.h.ah)) /*<2A>ha aparecido un error?*/
|
||||
return(EMS_ERR); /*S<>, mostrar error*/
|
||||
else /*no hay error*/
|
||||
return( regs.x.dx ); /*devolver n<>mero total de p<>ginas*/
|
||||
}
|
||||
|
||||
/**********************************************************************/
|
||||
/* Funci<63>n : E M S _ F R E E _ P A G E */
|
||||
/**--------------------------------------------------------------------**/
|
||||
/* Tarea : Obtiene la cantidad de p<>ginas EMS libres. */
|
||||
/* Par<61>metro entrada: ninguno */
|
||||
/* Valor de retorno : EMS_ERR en caso de error, sino el n<>mero de */
|
||||
/* p<>ginas EMS libres. */
|
||||
/***********************************************************************/
|
||||
|
||||
int ems_free_page()
|
||||
{
|
||||
union REGS regs; /*reg. de proc. para la llamada de interr.*/
|
||||
|
||||
regs.h.ah = 0x42; /*n<>mero de funci<63>n: obtener n<>mero de p<>ginas*/
|
||||
int86(EMS_INT, ®s, ®s); /*llamar EMM*/
|
||||
if ((int) (emm_ec = regs.h.ah)) /*<2A>ha aparecido un error?*/
|
||||
return(EMS_ERR); /*S<>, mostrar error*/
|
||||
else /*no hay error*/
|
||||
return( regs.x.bx ); /*devolver n<>mero de p<>ginas libres*/
|
||||
}
|
||||
|
||||
/**********************************************************************/
|
||||
/* Funci<63>n : E M S _ F R A M E _ S E G */
|
||||
/**--------------------------------------------------------------------**/
|
||||
/* Tarea : Obtiene la dir. de segmento del EMS-Page-Frame */
|
||||
/* Par<61>metro entrada: ninguno */
|
||||
/* Valor de retorno : EMS_ERR en caso de error, sino la direcci<63>n de */
|
||||
/* segmento del Page-Frame. */
|
||||
/***********************************************************************/
|
||||
|
||||
WORD ems_frame_seg()
|
||||
{
|
||||
union REGS regs; /*reg. de proc. para la llamada de interr.*/
|
||||
|
||||
regs.h.ah = 0x41; /*n<> de funci<63>n: obt.dir.segm. Page-Frame*/
|
||||
int86(EMS_INT, ®s, ®s); /*llamar EMM*/
|
||||
if ((int) (emm_ec = regs.h.ah)) /*<2A>ha aparecido un error?*/
|
||||
return(EMS_ERR); /*S<>, mostrar error*/
|
||||
else /*no hay error*/
|
||||
return( regs.x.bx ); /*devolver direcci<63>n de segmento*/
|
||||
}
|
||||
|
||||
/**********************************************************************/
|
||||
/* Funci<63>n : E M S _ A L L O C */
|
||||
/**--------------------------------------------------------------------**/
|
||||
/* Tarea : Aloja el n<>mero de p<>ginas indicado y devuelve */
|
||||
/* un Handle para acceder a estas p<>ginas. */
|
||||
/* */
|
||||
/* Par<61>metro entrada: PAGES : el n<>mero de p<>ginas a alojar */
|
||||
/* (de 16 KBytes cada uno) */
|
||||
/* Valor de retorno : EMS_ERR en caso de error, sino el Handle EMS. */
|
||||
/***********************************************************************/
|
||||
|
||||
int ems_alloc(int pages)
|
||||
{
|
||||
union REGS regs; /*reg. de proc. para la llamada de interr.*/
|
||||
|
||||
regs.h.ah = 0x43; /*n<>mero de funci<63>n: aljar p<>ginas*/
|
||||
regs.x.bx = pages; /*fijar n<>mero de p<>ginas a alojar*/
|
||||
int86(EMS_INT, ®s, ®s); /*llamar EMM*/
|
||||
if ((int) (emm_ec = regs.h.ah)) /*<2A>ha aparecido un error?*/
|
||||
return(EMS_ERR); /*S<>, mostrar error*/
|
||||
else /*no hay error*/
|
||||
return( regs.x.dx ); /*devolver Handle-EMS*/
|
||||
}
|
||||
|
||||
/**********************************************************************/
|
||||
/* Funci<63>n : E M S _ M A P */
|
||||
/**--------------------------------------------------------------------**/
|
||||
/* Tarea : Proyecta una de las p<>ginas alojadas bajo */
|
||||
/* el Handle indicado, a un p<>gina f<>sica del */
|
||||
/* del Page-Frame. */
|
||||
/* Par<61>metro entrada: HANDLE: el Handle devuelto por EMS_ALLOC */
|
||||
/* LOGP : la p<>gina l<>gica (0 a n-1) */
|
||||
/* PHYSP : la p<>gina f<>sica (0 a 3) */
|
||||
/* Valor de retorno : FALSE en caso de error, sino TRUE. */
|
||||
/***********************************************************************/
|
||||
|
||||
BOOL ems_map(int handle, int logp, BYTE physp)
|
||||
{
|
||||
union REGS regs; /*reg. de proc. para la llamada de interr.*/
|
||||
|
||||
regs.h.ah = 0x44; /*n<>mero de funci<63>n: fijar Maping*/
|
||||
regs.h.al = physp; /*fijar p<>gina f<>sica*/
|
||||
regs.x.bx = logp; /*fijar p<>gina l<>gica*/
|
||||
regs.x.dx = handle; /*fijar Handle EMS*/
|
||||
int86(EMS_INT, ®s, ®s); /*llamar EMM*/
|
||||
return (!(emm_ec = regs.h.ah));
|
||||
}
|
||||
|
||||
/**********************************************************************/
|
||||
/* Funci<63>n : E M S _ F R E E */
|
||||
/**--------------------------------------------------------------------**/
|
||||
/* Tarea : Devuelve la memoria alojada bajo un Handle */
|
||||
/* de nuevo. */
|
||||
/* Par<61>metro entrada: HANDLE: el Handle devuelto por EMS_ALLOC */
|
||||
/* Valor de retorno : FALSE en caso de error, sino TRUE. */
|
||||
/***********************************************************************/
|
||||
BOOL ems_free(int handle)
|
||||
{
|
||||
union REGS regs; /*reg. de proc. para la llamada de interr.*/
|
||||
|
||||
regs.h.ah = 0x45; /*n<>mero de funci<63>n: liberar p<>ginas*/
|
||||
regs.x.dx = handle; /*fijar Handle EMS*/
|
||||
int86(EMS_INT, ®s, ®s); /*llamar EMM*/
|
||||
return (!(emm_ec = regs.h.ah)); /*si AH contiene 0, todo est<73> ok*/
|
||||
}
|
||||
|
||||
/**********************************************************************/
|
||||
/* Funci<63>n : E M S _ V E R S I O N */
|
||||
/**--------------------------------------------------------------------**/
|
||||
/* Tarea : Obtiene el n<>mero de versi<73>n EMM. */
|
||||
/* Par<61>metro entrada: ninguno */
|
||||
/* Valor de retorno : EMS_ERR en caso de error, sino el n<>mero de */
|
||||
/* versi<73>n EMM. */
|
||||
/* Info : En el n<>mero de versi<73>n, 10 est<73> por 1.0, 11 */
|
||||
/* por 1.1, 34 por 3.4, etc. */
|
||||
/***********************************************************************/
|
||||
|
||||
BYTE ems_version()
|
||||
{
|
||||
union REGS regs; /*reg. de proc. para la llamada de interr.*/
|
||||
|
||||
regs.h.ah = 0x46; /*n<>mero de funci<63>n: obtener versi<73>n EMS*/
|
||||
int86(EMS_INT, ®s, ®s); /*llamar EMM*/
|
||||
if ((int) (emm_ec = regs.h.ah)) /*<2A>ha aparecido un error?*/
|
||||
return(EMS_ERR); /*S<>, mostrar error*/
|
||||
else /*sin error, calcula n<>mero de versi<73>n de cifra BCD*/
|
||||
return( (regs.h.al & 15) + (regs.h.al >> 4) * 10);
|
||||
}
|
||||
|
||||
/**********************************************************************/
|
||||
/* Funci<63>n : E M S _ S A V E _ M A P */
|
||||
/**--------------------------------------------------------------------**/
|
||||
/* Tarea : Guarda la proyecci<63>n (Mapping) entre p<>ginas */
|
||||
/* l<>gicas y f<>sicas. */
|
||||
/* Par<61>metro entrada: HANDLE: el Handle devuelto por EMS_ALLOC */
|
||||
/* Valor de retorno : FALSE en caso de error, sino TRUE. */
|
||||
/***********************************************************************/
|
||||
|
||||
BOOL ems_save_map(int handle)
|
||||
{
|
||||
union REGS regs; /*reg. de proc. para la llamada de interr.*/
|
||||
|
||||
regs.h.ah = 0x47; /*n<>mero de funci<63>n: guardar Mapping*/
|
||||
regs.x.dx = handle; /*fijar Handle EMS*/
|
||||
int86(EMS_INT, ®s, ®s); /*llamar EMM*/
|
||||
return (!(emm_ec = regs.h.ah)); /*si AH contiene 0, todo est<73> ok*/
|
||||
}
|
||||
|
||||
/**********************************************************************/
|
||||
/* Funci<63>n : E M S _ R E S T O R E _ M A P */
|
||||
/**--------------------------------------------------------------------**/
|
||||
/* Tarea : Recupera una proyecci<63>n entre p<>ginas l<>gicas */
|
||||
/* y f<>sicas guardada anteriormente mediante */
|
||||
/* EMS_SAVE_MAP. */
|
||||
/* Par<61>metro entrada: HANDLE: el Handle devuelto por EMS_ALLOC */
|
||||
/* Valor de retorno : FALSE en caso de error, sino TRUE. */
|
||||
/***********************************************************************/
|
||||
|
||||
BOOL ems_restore_map(int handle)
|
||||
{
|
||||
union REGS regs; /*reg. de proc. para la llamada de interr.*/
|
||||
|
||||
regs.h.ah = 0x48; /*n<>mero de funci<63>n: Recuperar Mapping*/
|
||||
regs.x.dx = handle; /*fijar Handle EMS*/
|
||||
int86(EMS_INT, ®s, ®s); /*llamar EMM*/
|
||||
return (!(emm_ec = regs.h.ah)); /*si AH contiene 0, todo est<73> ok*/
|
||||
}
|
||||
|
||||
/**********************************************************************/
|
||||
/* Funci<63>n : P R I N T _ E R R */
|
||||
/**--------------------------------------------------------------------**/
|
||||
/* Tarea : Visualiza un mensaje de error EMS en la pantalla */
|
||||
/* y termina el programa. */
|
||||
/* Par<61>metro entrada: ninguno */
|
||||
/* Valor de retorno : ninguno */
|
||||
/* Info : Esta funci<63>n s<>lo se puede llamar si durante */
|
||||
/* la llamada anterior de una funci<63>n del EMM */
|
||||
/* ha aparecido un error. */
|
||||
/***********************************************************************/
|
||||
|
||||
void print_err()
|
||||
{
|
||||
static char nid[] = "no identificable";
|
||||
static char *err_vec[] =
|
||||
{ "Error en el driver EMS (EMM destruido)", /*0x80*/
|
||||
"Error en el hardware EMS", /*0x81*/
|
||||
nid, /*0x82*/
|
||||
"Handle EMM no v<>lido", /*0x83*/
|
||||
"funci<EFBFBD>n EMS llamada no existe", /*0x84*/
|
||||
"no quedan Handles EMS disponibles", /*0x85*/
|
||||
"Error al guardar o recuperar el Mapping", /*0x86*/
|
||||
"m<EFBFBD>s p<>ginas pedidas de las que existen f<>sicamente", /*0x87*/
|
||||
"m<EFBFBD>s p<>ginas pedidas de las que quedan libres", /*0x88*/
|
||||
"pedidad cero p<>ginas", /*0x89*/
|
||||
"p<EFBFBD>gina l<>gica no pertenece al Handle", /*0x8A*/
|
||||
"n<EFBFBD>mero de p<>gina f<>sico no v<>lido", /*0x8B*/
|
||||
"Zona de memoria mapping est<73> llena", /*0x8C*/
|
||||
"Guardado del mapping ya se realiz<69>", /*0x8D*/
|
||||
"Recuperar el mapping sin guardarlo previamente"
|
||||
};
|
||||
|
||||
printf("\nATENCION! Error al acceder a la memoria EMS!r\n");
|
||||
printf(" ... %s\n", (emm_ec<0x80 || emm_ec>0x8E) ?
|
||||
nid : err_vec[emm_ec-0x80]);
|
||||
exit( 1 ); /*terminar programa con c<>digo de error*/
|
||||
}
|
||||
|
||||
/**********************************************************************/
|
||||
/* Funci<63>n : V R _ A D R */
|
||||
/**------------------------------------------------------------------**/
|
||||
/* Tarea : Devuelve un puntero a la RAM de v<>deo. */
|
||||
/* Par<61>metro entrada: ninguno */
|
||||
/* Valor de retorno : Puntero VOID a la RAM de v<>deo. */
|
||||
/**********************************************************************/
|
||||
|
||||
void *vr_adr()
|
||||
{
|
||||
union REGS regs; /*reg. de proc. para la llamada de interr.*/
|
||||
|
||||
regs.h.ah = 0x0f; /*n<>mero de funci<63>n:obtener modo de v<>deo*/
|
||||
int86(0x10, ®s, ®s); /*llamar interrupci<63>n de la BIOS de v<>deo*/
|
||||
return ( MK_FP((regs.h.al==7) ? 0xb000 : 0xb800, 0) );
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************/
|
||||
/** PROGRAMA PRINCIPAL **/
|
||||
/**********************************************************************/
|
||||
////
|
||||
////void main()
|
||||
////{
|
||||
//// int pagenum, /*n<>mero de p<>ginas EMS*/
|
||||
//// handle, /*Handle para acceder a la memoria EMS*/
|
||||
//// i; /*contador de bucle*/
|
||||
//// WORD pageseg ; /*direcci<63>n de segmento del Page-Frame*/
|
||||
//// BYTE emmver; /*n<>mero de versi<73>n de la EMM*/
|
||||
////
|
||||
//// printf("EMMC - (c) 1988, 92 by MICHAEL TISCHER\n\n");
|
||||
//// if ( ems_inst() ) /*<2A>Est<73> instalada la memoria EMS?*/
|
||||
//// { /*Si*/
|
||||
//// /*-- Visualizar informaciones sobre la memoria EMS ----------------*/
|
||||
////
|
||||
//// if ( (int) (emmver = ems_version()) == EMS_ERR) /*Obten. n<> versi<73>n*/
|
||||
//// print_err(); /*Error: visualizar men. error y term. el programa*/
|
||||
//// else /*no hay error*/
|
||||
//// printf("N<>mero de versi<73>n EMM : %d.%d\n",
|
||||
//// emmver/10, emmver%10);
|
||||
////
|
||||
//// if ( (pagenum = ems_num_page()) == EMS_ERR) /*obten. n<> p<>ginas*/
|
||||
//// print_err(); /*Error: vis. men. de error y terminar el programa*/
|
||||
//// printf("N<>mero de p<>ginas EMS : %d (%d KByte)\n",
|
||||
//// pagenum, pagenum << 4);
|
||||
////
|
||||
//// if ( (pagenum = ems_free_page()) == EMS_ERR)
|
||||
//// print_err(); /*Error: vis. men. error y terminar el programa*/
|
||||
//// printf("... libres : %d (%d KByte)\n",
|
||||
//// pagenum, pagenum << 4);
|
||||
////
|
||||
//// if ( (int) (pageseg = ems_frame_seg()) == EMS_ERR)
|
||||
//// print_err(); /*Error: vis. men. error y terminar el programa*/
|
||||
//// printf("Direcc. segmento del Page-Frame: %X\n", pageseg);
|
||||
////
|
||||
//// printf("\nAhora se aloja una p<>gina de la memoria EMS, y el con-\n");
|
||||
//// printf("tenido de la pantalla de la RAM de v<>deo se copia a\n");
|
||||
//// printf("esta p<>gina.\n");
|
||||
//// printf(" ... por favor pulse una tecla\n");
|
||||
//// getch(); /*esperar una tecla*/
|
||||
////
|
||||
//// /*-- alojar una p<>gina y poyectar sobre la primera p<>gina l<>gica --*/
|
||||
//// /*-- en el Page-Frame ---*/
|
||||
////
|
||||
//// if ( (handle = ems_alloc(1)) == EMS_ERR)
|
||||
//// print_err(); /*Error: vis. men. error y terminar el programa*/
|
||||
//// if ( !ems_map(handle, 0, 0) ) /*fijar Mapping*/
|
||||
//// print_err(); /*Error: vis. men. de error y terminar el programa*/
|
||||
////
|
||||
//// /*-- Copiar 4000 bytes de la RAM de v<>deo a la memoria EMS ----*/
|
||||
////
|
||||
//// memcpy(PAGE_ADR(0), vr_adr(), 4000);
|
||||
////
|
||||
//// for (i=0; i<24; ++i) /*borrar la pantalla*/
|
||||
//// printf("\n");
|
||||
////
|
||||
//// printf("El antiguo contenido de la pantalla ha sido borrado y\n");
|
||||
//// printf("con ello se ha perdido. Pero como ha sido guardado en\n");
|
||||
//// printf("la memoria EMS, se puede volver a copiar de all<6C> a la\n");
|
||||
//// printf("RAM de v<>deo.\n");
|
||||
//// printf(" ... por favor pulse una tecla\n");
|
||||
//// getch(); /*esperar una tecla*/
|
||||
////
|
||||
//// /*-- copiar de nuevo el contenido de la RAM de v<>deo de la memo----*/
|
||||
//// /*-- ria EMS y devolver la memoria EMS alojada ----*/
|
||||
////
|
||||
//// memcpy(vr_adr(), PAGE_ADR(0), 4000); /*copiar la V-RAM de vuelta*/
|
||||
//// if ( !ems_free(handle) ) /*liberar memoria*/
|
||||
//// print_err(); /*Error: vis. men. error y terminar el programa*/
|
||||
//// printf("FIN");
|
||||
//// }
|
||||
//// else /*el driver EMS no se descubri<72>*/
|
||||
//// printf("ATENCION: No hay memoria EMS instalada.\n");
|
||||
////}
|
Reference in New Issue
Block a user