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

403 lines
20 KiB
C++
Raw Permalink 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.

/**********************************************************************/
/* E M M C */
/*--------------------------------------------------------------------*/
/* Tarea : contiene algunas funciones para acceder a la */
/* memoria EMS (Expanded Memory) */
/*--------------------------------------------------------------------*/
/* Autor : MICHAEL TISCHER */
/* desarrollado el: 30.08.1988 */
/* £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¢n de segmento y Offset un -------------*/
/*-- puntero FAR a un objeto -------*/
#ifdef MK_FP /*¨ya se defini¢ 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¢n para acceder a la EMM*/
#define EMS_ERR -1 /*se devuelve en caso de error*/
/*== variables globales===============================================*/
BYTE emm_ec; /*aqu¡ se guardan los c¢digos de error EMM*/
/***********************************************************************/
/* Funci¢n : E M S _ I N S T */
/**--------------------------------------------------------------------**/
/* Tarea : Determina si hay instalada memoria EMS, y un */
/* driver EMS (EMM) asociado. */
/* Par 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(&regs, &regs, &sregs); /*llamar la interr. del DOS 0x21*/
return !memcmp( MK_FP(sregs.es, 10), emm_name, sizeof emm_name );
}
/************************************************************************/
/* Funci¢n : E M S _ N U M _ P A G E */
/**--------------------------------------------------------------------**/
/* Tarea : Obtiene el n§ total de p ginas EMS. */
/* Par 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¢n: obtener n£mero de p ginas*/
int86(EMS_INT, &regs, &regs); /*llamar EMM*/
if ((int) (emm_ec = regs.h.ah)) /*¨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¢n : E M S _ F R E E _ P A G E */
/**--------------------------------------------------------------------**/
/* Tarea : Obtiene la cantidad de p ginas EMS libres. */
/* Par 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¢n: obtener n£mero de p ginas*/
int86(EMS_INT, &regs, &regs); /*llamar EMM*/
if ((int) (emm_ec = regs.h.ah)) /*¨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¢n : E M S _ F R A M E _ S E G */
/**--------------------------------------------------------------------**/
/* Tarea : Obtiene la dir. de segmento del EMS-Page-Frame */
/* Par metro entrada: ninguno */
/* Valor de retorno : EMS_ERR en caso de error, sino la direcci¢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¢n: obt.dir.segm. Page-Frame*/
int86(EMS_INT, &regs, &regs); /*llamar EMM*/
if ((int) (emm_ec = regs.h.ah)) /*¨ha aparecido un error?*/
return(EMS_ERR); /*S¡, mostrar error*/
else /*no hay error*/
return( regs.x.bx ); /*devolver direcci¢n de segmento*/
}
/**********************************************************************/
/* Funci¢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 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¢n: aljar p ginas*/
regs.x.bx = pages; /*fijar n£mero de p ginas a alojar*/
int86(EMS_INT, &regs, &regs); /*llamar EMM*/
if ((int) (emm_ec = regs.h.ah)) /*¨ha aparecido un error?*/
return(EMS_ERR); /*S¡, mostrar error*/
else /*no hay error*/
return( regs.x.dx ); /*devolver Handle-EMS*/
}
/**********************************************************************/
/* Funci¢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 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¢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, &regs, &regs); /*llamar EMM*/
return (!(emm_ec = regs.h.ah));
}
/**********************************************************************/
/* Funci¢n : E M S _ F R E E */
/**--------------------------------------------------------------------**/
/* Tarea : Devuelve la memoria alojada bajo un Handle */
/* de nuevo. */
/* Par 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¢n: liberar p ginas*/
regs.x.dx = handle; /*fijar Handle EMS*/
int86(EMS_INT, &regs, &regs); /*llamar EMM*/
return (!(emm_ec = regs.h.ah)); /*si AH contiene 0, todo est  ok*/
}
/**********************************************************************/
/* Funci¢n : E M S _ V E R S I O N */
/**--------------------------------------------------------------------**/
/* Tarea : Obtiene el n£mero de versi¢n EMM. */
/* Par metro entrada: ninguno */
/* Valor de retorno : EMS_ERR en caso de error, sino el n£mero de */
/* versi¢n EMM. */
/* Info : En el n£mero de versi¢n, 10 est  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¢n: obtener versi¢n EMS*/
int86(EMS_INT, &regs, &regs); /*llamar EMM*/
if ((int) (emm_ec = regs.h.ah)) /*¨ha aparecido un error?*/
return(EMS_ERR); /*S¡, mostrar error*/
else /*sin error, calcula n£mero de versi¢n de cifra BCD*/
return( (regs.h.al & 15) + (regs.h.al >> 4) * 10);
}
/**********************************************************************/
/* Funci¢n : E M S _ S A V E _ M A P */
/**--------------------------------------------------------------------**/
/* Tarea : Guarda la proyecci¢n (Mapping) entre p ginas */
/* l¢gicas y f¡sicas. */
/* Par 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¢n: guardar Mapping*/
regs.x.dx = handle; /*fijar Handle EMS*/
int86(EMS_INT, &regs, &regs); /*llamar EMM*/
return (!(emm_ec = regs.h.ah)); /*si AH contiene 0, todo est  ok*/
}
/**********************************************************************/
/* Funci¢n : E M S _ R E S T O R E _ M A P */
/**--------------------------------------------------------------------**/
/* Tarea : Recupera una proyecci¢n entre p ginas l¢gicas */
/* y f¡sicas guardada anteriormente mediante */
/* EMS_SAVE_MAP. */
/* Par 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¢n: Recuperar Mapping*/
regs.x.dx = handle; /*fijar Handle EMS*/
int86(EMS_INT, &regs, &regs); /*llamar EMM*/
return (!(emm_ec = regs.h.ah)); /*si AH contiene 0, todo est  ok*/
}
/**********************************************************************/
/* Funci¢n : P R I N T _ E R R */
/**--------------------------------------------------------------------**/
/* Tarea : Visualiza un mensaje de error EMS en la pantalla */
/* y termina el programa. */
/* Par metro entrada: ninguno */
/* Valor de retorno : ninguno */
/* Info : Esta funci¢n s¢lo se puede llamar si durante */
/* la llamada anterior de una funci¢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¢n EMS llamada no existe", /*0x84*/
"no quedan Handles EMS disponibles", /*0x85*/
"Error al guardar o recuperar el Mapping", /*0x86*/
"m s p ginas pedidas de las que existen f¡sicamente", /*0x87*/
"m s p ginas pedidas de las que quedan libres", /*0x88*/
"pedidad cero p ginas", /*0x89*/
"p gina l¢gica no pertenece al Handle", /*0x8A*/
"n£mero de p gina f¡sico no v lido", /*0x8B*/
"Zona de memoria mapping est  llena", /*0x8C*/
"Guardado del mapping ya se realiz¢", /*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¢n : V R _ A D R */
/**------------------------------------------------------------------**/
/* Tarea : Devuelve un puntero a la RAM de v¡deo. */
/* Par 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¢n:obtener modo de v¡deo*/
int86(0x10, &regs, &regs); /*llamar interrupci¢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¢n de segmento del Page-Frame*/
//// BYTE emmver; /*n£mero de versi¢n de la EMM*/
////
//// printf("EMMC - (c) 1988, 92 by MICHAEL TISCHER\n\n");
//// if ( ems_inst() ) /*¨Est  instalada la memoria EMS?*/
//// { /*Si*/
//// /*-- Visualizar informaciones sobre la memoria EMS ----------------*/
////
//// if ( (int) (emmver = ems_version()) == EMS_ERR) /*Obten. n§ versi¢n*/
//// print_err(); /*Error: visualizar men. error y term. el programa*/
//// else /*no hay error*/
//// printf("N£mero de versi¢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¡ 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¢*/
//// printf("ATENCION: No hay memoria EMS instalada.\n");
////}