www.pudn.com > fxvmm210.zip > _FXAPI.C
/*
API functions used by the FXúVM Manager version 2.10
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "..\source.c\_fxapi.h"
/*
Externally avalaible variables
*/
unsigned char fxvmm_fxapi_active = FALSE;
unsigned char fxvmm_ems_api_installed = FALSE;
unsigned char fxvmm_ems_api_name[] = "EMMXXXX0";
unsigned int fxvmm_ems_api_frame = 0;
unsigned char fxvmm_ems_api_vermajor = 0;
unsigned char fxvmm_ems_api_verminor = 0;
unsigned long fxvmm_ems_api_size = 0L;
unsigned long fxvmm_ems_api_free = 0L;
unsigned int fxvmm_ems_api_totalhandle = 0;
unsigned int fxvmm_ems_api_freehandle = 0;
unsigned int fxvmm_ems_api_usehandle = 0;
unsigned char fxvmm_xms_api_installed = FALSE;
unsigned long fxvmm_xms_api_free = 0L;
unsigned long fxvmm_xms_api_largest = 0L;
unsigned char fxvmm_xms_api_vermajor = 0;
unsigned char fxvmm_xms_api_verminor = 0;
unsigned char fxvmm_xms_api_hma = 0;
unsigned char fxvmm_xms_api_a20 = 0;
unsigned int fxvmm_xms_api_usehandle = 0;
unsigned int fxvmm_xms_api_freehandle = 0;
unsigned char fxvmm_umb_api_installed = FALSE;
unsigned long fxvmm_umb_api_free = 0L;
unsigned long fxvmm_umb_api_large = 0L;
unsigned int fxvmm_umb_api_index = 0;
unsigned long fxvmm_vrt_api_free = 0L;
unsigned long fxvmm_dos_api_free = 0L;
unsigned char fxvmm_dosextender = FXVMM_DOS_REALMODE ;
unsigned char fxvmm_protmode = FXVMM_DOSV86 ;
unsigned char fxvmm_windows = FXVMM_WINDOWS_NONE ;
/*
Static/Local Variables
*/
static unsigned char far *fxvmm_stack_st_top = NULL ;
static unsigned char far *fxvmm_stack_st_bot = NULL ;
static unsigned char far *fxvmm_stack_prt = NULL ;
static unsigned int fxvmm_stack_segment = 0x0000U ;
static unsigned int fxvmm_stack_st_ptr = 0x0000U ;
static unsigned char fxvmm_stack_mark = 0xFFU ;
static unsigned int fxvmm_stack_unused = 0x0000U ;
static FXVMM_EMSHANDLE fxvmm_ems_api_handles[FXVMM_MAXHANDLES];
static FXVMM_XMSHANDLE fxvmm_xms_api_handles[FXVMM_MAXHANDLES];
static void far (*fxvmm_xmsdrv_apicall)(void);
static FXVMM_MCBHEAD *fxvmm_firstmcb=NULL;
static FXVMM_MEMINFO fxvmm_mlist[FXVMM_MAXITEM];
static unsigned int fxvmm_mlistnum=0;
static unsigned char *fxvmm_system_typenames[]=
{
" ",
"System code ",
"System data ",
"Program ",
"Device driver",
"Environment ",
"Data area ",
"Free ",
};
int _fxvmm_vrt_handle_swapwipe( const char *filename )
{
FILE *stream ;
struct ftime ft ;
unsigned long loop ;
unsigned char name[13] ;
unsigned char dod_loop ;
/*
Steps to wipe a file
(1) Change attributes to Archive-bit only
(2) open file and set date and time to 00/00/00 00:00:12a
(3) Wipe file according to DoD 5220.22-M specs
i.e. Overwrite file with 0xFF
Overwrite file with 0x00
Do this 3 times, and then Overwrite file with 246 (0xf6)
(4) Truncanate it to 0 bytes
(5) Create temp name and rename it to that name
(6) Delete that file
*/
_chmod( filename , 1 , !FA_RDONLY );
_chmod( filename , 1 , !FA_HIDDEN );
_chmod( filename , 1 , !FA_SYSTEM );
_chmod( filename , 1 , FA_ARCH );
/* Note we're resetting the filedate's year to 0 by setting it to
-108 ... confused ? ... well DOS doesn't have a year '0', in fact
the lowest it can reach is 1980, this is just a little trick to
make it '0' ... note that some anti-virus programs tell the user
that the program might be infected with a virus if the date of the
file is invalid (and this one is...) - shame on those av's ! */
ft.ft_year = -108 ; /* make it 0 */
ft.ft_month = 0U ; /* make it 0 */
ft.ft_day = 0U ; /* make it 0 */
ft.ft_hour = 0U ; /* make it 0 */
ft.ft_min = 0U ; /* make it 0 */
ft.ft_tsec = 0U ; /* make it 0 */
if( ( stream = fopen( filename , "r+b" ) ) == NULL )
return( FALSE ); /* open for readin' & writin' */
for( dod_loop = 0U ; dod_loop < 3U ; dod_loop++ ) /* start wiping */
{
rewind( stream );
for( loop = 0LU ; loop < fxvmm_vrt_swapsize ; loop ++ )
putc( dod_loop == 0 || dod_loop == 2 ? 0xff : 0x00 , stream );
}
for( loop = 0LU ; loop < fxvmm_vrt_swapsize ; loop ++ ) /* Wipe for the last time */
putc( 0xf6 , stream );
fclose( stream ); /* close file */
if( ( stream = fopen( filename , "wb" ) ) == NULL ) /* kill to 0 bytes */
return( FALSE );
setftime( fileno( stream ), &ft ); /* reset time & date */
fclose( stream ); /* re-close file */
randomize();
for( loop = 0U ; loop < 8U ; loop ++ ) /* make up a name */
name[ loop ] = (random(9) + '0');
name[8] = '.'; /* add a extension marker */
for( loop = 9U ; loop < 12U ; loop ++ ) /* add extension */
name[ loop ] = (random(9) + '0');
name[ loop ] = '\0'; /* Terminate string */
rename( filename , name ); /* rename file */
unlink( name ); /* And finally, remove it */
return( TRUE );
}
char *_fxvmm_vrt_handle_buildswap( void )
{
char *ptr = NULL ; /* pointer to the environment */
/* first check the DOS environment for the 'TEMP' or 'TMP' setting,
if there isn't any setting in the environment, call the mktemp()
function wich will create a temporary name for us */
if( (ptr = getenv("TEMP")) == NULL && (ptr = getenv("TMP")) == NULL )
return( mktemp("VMXXXXXX") );
else
{
char *path ;
/* Allocate some memory for the swapname, if there's not enough
memory we could either exit and tell the user, since this is
a pretty stupid thing ... like imagine this error message :
Error: The virtual memory manager just ran out of memory ... ehmm
Yeah, get my point ?, so if there isn't enough memory (wich would
be wierd in the first place, but anyway, if there isn't any we
just return the mktemp() function wich will do it for us */
if( ( path = malloc(80)) == NULL )
return( mktemp("VMXXXXXX") );
strcpy( path , ptr );
/* Now check if there's a trailing slash, if not append one */
if( path[ strlen(path) - 1 ] != '\\' )
strcat( path , "\\" );
/* Append a swapname to the tempoary path */
strcat( path , mktemp("VMXXXXXX") );
return( path );
}
}
int _fxvmm_vrt_handle_swapunlink( const char *swapname )
{
if( swapname != NULL && fxvmm_vrt_swapsize != 0 )
{
#ifdef FXVMM_WIPESWAP
return( _wipe_file( swapname ) );
#else
return( unlink( swapname ) );
#endif
}
return( TRUE );
}
char _fxvmm_open_api( void )
{
if( _osmajor == 3 ) /* We require a DOS version above 3.1 */
{
if( _osminor < 1 )
return( FALSE );
}
else
if( _osmajor < 3 ) /* We require a DOS version above 3.1 */
return( FALSE );
/* Call the CPU identification routine */
_fxvmm_cpuid();
if( fxvmm_cputype < 3U ) /* Only 386's and above */
return( FALSE );
/* Check wich DOS extender we're running on */
_fxvmm_getdosextender();
/* Are we in protected mode (of so wich one), or in real mode ? */
fxvmm_protmode = _fxvmm_detprotmode();
/* Are we running under windows (if so wich one), or DOS */
fxvmm_windows = _fxvmm_detwin();
if( _fxvmm_check_ems() == ERROR ) /* check to see if EMS is okay (i.e. not corrupted) */
return( FALSE );
if( _fxvmm_check_xms() == ERROR ) /* check to see if XMS is okay (i.e. not corrupted) */
return( FALSE );
if( _fxvmm_check_umb() == ERROR ) /* check to see if UMB's are okay (i.e. not corrupted) */
return( FALSE );
if( _fxvmm_check_dos() == ERROR ) /* check to see if DOS is okay (i.e. not corrupted) */
return( FALSE );
if( _fxvmm_check_vrt() == ERROR ) /* check to see if VRT is okay (i.e. not corrupted) */
return( FALSE );
fxvmm_fxapi_active = TRUE ; /* The API is active now ! */
return( _fxvmm_initialize() );
}
char _fxvmm_close_api( void )
{
_fxvmm_deinitialize();
fxvmm_fxapi_active = FALSE ; /* API not active anymore */
if( _fxvmm_check_ems() == ERROR ) /* check to see if EMS is okay (i.e. not corrupted) */
return( FALSE );
if( _fxvmm_check_xms() == ERROR ) /* check to see if XMS is okay (i.e. not corrupted) */
return( FALSE );
if( _fxvmm_check_umb() == ERROR ) /* check to see if UMB's are okay (i.e. not corrupted) */
return( FALSE );
if( _fxvmm_check_dos() == ERROR ) /* check to see if DOS is okay (i.e. not corrupted) */
return( FALSE );
if( _fxvmm_check_vrt() == ERROR ) /* check to see if VRT is okay (i.e. not corrupted) */
return( FALSE );
return( TRUE );
}
/*
Returns wich DOS extender is active
*/
void _fxvmm_getdosextender( void )
{
union REGS regs;
struct SREGS segregs;
regs.x.ax = 0x2B00;
regs.x.cx = 0x4149; /* "AI" */
regs.x.dx = 0x413F; /* "A?" */
int86(0x21, ®s, ®s);
if( regs.x.ax == 0x4149 )
{
if( regs.x.cx == 0x0202 )
fxvmm_dosextender = FXVMM_ERGO_OS286;
else
if( regs.x.cx == 0x0203 )
{
segread(&segregs);
if( segregs.cs == 0x0F )
fxvmm_dosextender = FXVMM_ERGO_OS386;
else
fxvmm_dosextender = FXVMM_ERGO_OS286;
}
}
else
{
regs.x.ax = 0x3000;
regs.x.bx = 0x50484152; /* "PHAR" */
int86( 0x21, ®s, ®s );
regs.x.ax &= 0xFFFF0000;
#pragma warn -rng
if( regs.x.ax == 0x44580000 ) /* "DX00" */
fxvmm_dosextender = FXVMM_PHARLAP_386;
#pragma warn +rng
}
}
/*
Check wether EMS exists, and wether it's corrupted or not
*/
char _fxvmm_check_ems( void )
{
void far *int67 ;
int67 = (void *)getvect(0x67);
if( int67 == NULL )
return( ERROR );
asm push ds
asm push si
asm push di
asm les di,int67
asm mov di,10
asm lea si,fxvmm_ems_api_name
asm mov cx,8
asm cld
asm repe cmpsb
asm pop di
asm pop si
asm pop ds
asm jz _found
return( FALSE );
_found:
fxvmm_ems_api_installed = TRUE;
asm mov ah,41h
asm int 67h
asm or ah,ah
asm jnz _error
asm mov fxvmm_ems_api_frame,bx
asm mov ah,46h
asm int 67h
asm or ah,ah
asm jnz _error
asm mov bl,al
asm and al,0fh
asm and bl,0f0h
asm mov cl,4
asm shr bl,cl
asm mov fxvmm_ems_api_vermajor,bl
asm mov fxvmm_ems_api_verminor,al
asm mov ah,42h
asm int 67h
asm or ah,ah
asm jnz _error
asm mov word ptr fxvmm_ems_api_size,dx
asm mov word ptr fxvmm_ems_api_size[2],0
asm mov word ptr fxvmm_ems_api_free,bx
asm mov word ptr fxvmm_ems_api_free[2],0
fxvmm_ems_api_size *= 16384L;
fxvmm_ems_api_free *= 16384L;
asm push di
_ES=FP_SEG( &fxvmm_ems_api_handles );
_DI=FP_OFF( &fxvmm_ems_api_handles );
asm mov ah,4Dh
asm int 67h
asm pop di
asm or ah,ah
asm jnz _error
asm mov fxvmm_ems_api_usehandle,bx
if( fxvmm_ems_api_vermajor >= 4 )
{
asm mov ax,5402h
asm int 67h
asm or ah,ah
asm jnz _error
asm mov fxvmm_ems_api_totalhandle,bx
}
else
fxvmm_ems_api_totalhandle = fxvmm_ems_api_usehandle;
fxvmm_ems_api_freehandle = (fxvmm_ems_api_totalhandle - fxvmm_ems_api_usehandle);
return( TRUE );
_error: return( ERROR );
}
/*
Check wether XMS exists, and wether it's corrupted or not
*/
char _fxvmm_check_xms( void )
{
asm mov ax,4300h
asm int 2fh
asm cmp al,80h
asm je _found
return( FALSE );
_found:
fxvmm_xms_api_installed = TRUE;
asm mov ax,4310h
asm int 2fh
asm mov word ptr fxvmm_xmsdrv_apicall,bx
asm mov word ptr fxvmm_xmsdrv_apicall[2],es
asm mov ah,0
(*fxvmm_xmsdrv_apicall)();
asm mov fxvmm_xms_api_vermajor,ah
asm mov fxvmm_xms_api_verminor,al
asm mov fxvmm_xms_api_hma,dl
asm mov ah,8
(*fxvmm_xmsdrv_apicall)();
asm mov word ptr fxvmm_xms_api_free,ax
asm mov word ptr fxvmm_xms_api_free[2],0
asm mov word ptr fxvmm_xms_api_largest,dx
asm mov word ptr fxvmm_xms_api_largest[2],0
fxvmm_xms_api_free *= 1024L;
fxvmm_xms_api_largest *= 1024L;
asm mov ah,7
(*fxvmm_xmsdrv_apicall)();
asm or bl,bl
asm jnz _error
asm mov fxvmm_xms_api_a20,al
return( TRUE );
_error: return( ERROR );
}
/*
Check wether DOS is corrupted or not
*/
char _fxvmm_check_dos( void )
{
if( heapcheck() == -1 )
return( ERROR );
(size_t)fxvmm_dos_api_free = coreleft();
return( TRUE );
}
/*
Check wether DOS is corrupted or not
*/
char _fxvmm_check_vrt( void )
{
struct dfree free ;
unsigned int drive ;
if( fxvmm_fxapi_active )
{
if( fxvmm_vrt_swaphandle == 0x0000 )
drive = getdisk();
else
drive = fxvmm_vrt_swaphandle ;
}
else
drive = getdisk();
getdfree( drive + 1 , &free );
if ( free.df_sclus == 0xFFFF )
return( ERROR );
else
if( ( fxvmm_vrt_api_free = (unsigned long)free.df_avail * (unsigned long)free.df_bsec * (unsigned long)free.df_sclus ) == 0LU )
return( FALSE );
return( TRUE );
}
/*
Check wether an upper-memory block link is established
*/
unsigned char _fxvmm_get_umblink( void )
{
asm mov ax,5802h
asm int 21h
return( _AL );
}
/*
Establish an upper-memory block link
*/
int _fxvmm_set_umblink( unsigned char link )
{
asm mov ax,5803h
asm xor bh,bh
asm mov bl,link
asm int 21h
asm jc _noumb
return( TRUE );
_noumb:
asm cmp ax,1
asm jne _trash
return( FALSE );
_trash: return( ERROR );
}
/*
Check wether UMB is present, and not corrupted
*/
char _fxvmm_check_umb( void )
{
unsigned char origlink;
origlink = _fxvmm_get_umblink();
switch( _fxvmm_set_umblink(1) )
{
case TRUE : fxvmm_umb_api_installed = TRUE ;
break;
case FALSE : fxvmm_umb_api_installed = FALSE;
break;
case ERROR : return( ERROR );
}
_fxvmm_set_umblink( origlink );
return( TRUE );
}
/*
Check if the MCB contains an _psp
*/
int _fxvmm_ispsp( FXVMM_MCBHEAD *mcb )
{
asm les bx,mcb
asm mov ax,es
asm inc ax
asm mov es,ax
asm mov ax, TRUE
asm cmp word ptr es:[bx],20CDh
asm je __exit
asm mov ax,FALSE
__exit:
return( _AX );
}
/*
Return the segment of the environment from the given MCB
*/
unsigned int _fxvmm_envseg( FXVMM_MCBHEAD *mcb )
{
FXVMM_MCBHEAD *env;
asm les bx,mcb
asm mov ax,es
asm inc ax
asm mov es,ax
asm mov bx,ax
asm mov ax,es:[2Ch]
asm dec ax
asm mov es,ax
asm inc ax
asm cmp es:[1],bx
asm je __exit
asm mov ax,0
__exit:
return( _AX );
}
/*
Seach the vector table
*/
void _fxvmm_search_vectors( FXVMM_MEMINFO *m )
{
unsigned int i;
unsigned long begin, end, iv;
unsigned char far *ivp;
begin = (unsigned long)( (m -> seg) + 1) << 4;
end = begin + (m -> size) ;
for( i = 0 ; i < 256 ; i++ )
{
memcpy(&ivp, MK_FP(0, i*4), 4);
iv = ((unsigned long)(FP_SEG(ivp) + 1) << 4) + (unsigned long)FP_OFF(ivp);
if( ( iv > begin ) && ( iv < end ) && ( (m -> vecnum) < FXVMM_MAXVECTOR ) )
(m -> vectors[ (m -> vecnum++) ]) = (unsigned char)i;
}
}
/*
Seach the sd
*/
void _fxvmm_searchsd( FXVMM_MCBHEAD *mcb )
{
unsigned int begin, end;
FXVMM_SDHEAD *sd;
sd = MK_FP(FP_SEG(mcb) + 1, 0);
begin = FP_SEG(mcb);
end = FP_SEG(mcb) + mcb->size;
while((FP_SEG(sd) > begin) && (FP_SEG(sd) < end) && (fxvmm_mlistnum < FXVMM_MAXITEM))
{
fxvmm_mlistnum++;
fxvmm_mlist[fxvmm_mlistnum].seg = (sd -> start);
fxvmm_mlist[fxvmm_mlistnum].size = (unsigned long)(sd -> size) << 4;
switch( (sd -> type) )
{
case 'D':
case 'I': fxvmm_mlist[fxvmm_mlistnum].name[0]=' ';
strncpy(&fxvmm_mlist[fxvmm_mlistnum].name[1], sd->name, 8);
strupr(fxvmm_mlist[fxvmm_mlistnum].name);
fxvmm_mlist[fxvmm_mlistnum].type=FXVMM_MTDEV;
break;
case 'F': strcpy(fxvmm_mlist[fxvmm_mlistnum].name, " FILES");
fxvmm_mlist[fxvmm_mlistnum].type=FXVMM_MTDATA;
break;
case 'X': strcpy(fxvmm_mlist[fxvmm_mlistnum].name, " FCBS");
fxvmm_mlist[fxvmm_mlistnum].type=FXVMM_MTDATA;
break;
case 'C':
case 'B': strcpy(fxvmm_mlist[fxvmm_mlistnum].name, " BUFFERS");
fxvmm_mlist[fxvmm_mlistnum].type=FXVMM_MTDATA;
break;
case 'L': strcpy(fxvmm_mlist[fxvmm_mlistnum].name, " LASTDRV");
fxvmm_mlist[fxvmm_mlistnum].type=FXVMM_MTDATA;
break;
case 'S': strcpy(fxvmm_mlist[fxvmm_mlistnum].name, " STACKS");
fxvmm_mlist[fxvmm_mlistnum].type=FXVMM_MTDATA;
break;
default: strcpy(fxvmm_mlist[fxvmm_mlistnum].name, " UNKNOWN");
fxvmm_mlist[fxvmm_mlistnum].type=FXVMM_MTDATA;
break;
}
sd = MK_FP( (sd -> start) + (sd -> size), 0);
}
}
/*
Check name for valid ASCII characters
*/
void check_name( unsigned char *name )
{
unsigned int i;
for( i = 0 ; name[i] ; i++ )
if( name[i] < 0x20 )
{
name[i] = '\0';
break;
}
}
/*
Register an MCB
*/
void _fxvmm_regmcb( FXVMM_MCBHEAD *mcb )
{
fxvmm_mlist[fxvmm_mlistnum].seg = FP_SEG(mcb);
fxvmm_mlist[fxvmm_mlistnum].owner = mcb->owner;
fxvmm_mlist[fxvmm_mlistnum].size = (unsigned long)mcb->size << 4;
if( fxvmm_mlist[fxvmm_mlistnum].seg <= 0x9FFF )
{
if( _fxvmm_ispsp(mcb) )
{
strncpy(fxvmm_mlist[fxvmm_mlistnum].name, mcb->name, 8);
check_name(fxvmm_mlist[fxvmm_mlistnum].name);
strupr(fxvmm_mlist[fxvmm_mlistnum].name);
fxvmm_mlist[fxvmm_mlistnum].environment = _fxvmm_envseg(mcb);
fxvmm_mlist[fxvmm_mlistnum].type = FXVMM_MTAPP;
}
if( !(mcb -> owner) )
fxvmm_mlist[fxvmm_mlistnum].type = FXVMM_MTFREE;
else
if( (mcb -> owner) <= 0x0008 )
{
strcpy(fxvmm_mlist[fxvmm_mlistnum].name, "DOS");
if( !strncmp(mcb->name, "SD", 2) )
{
fxvmm_mlist[fxvmm_mlistnum].type=FXVMM_MTSYSDATA;
_fxvmm_searchsd(mcb);
}
else
if( !strncmp(mcb->name, "SC", 2) )
fxvmm_mlist[fxvmm_mlistnum].type = FXVMM_MTSYSCODE;
else
fxvmm_mlist[fxvmm_mlistnum].type = FXVMM_MTSYSCODE;
}
}
else
{
if( !(mcb -> owner) )
fxvmm_mlist[fxvmm_mlistnum].type = FXVMM_MTFREE;
else
if( (mcb -> owner) <= 0x0008 )
{
strcpy(fxvmm_mlist[fxvmm_mlistnum].name, "DOS");
if( !strncmp(mcb->name, "SD", 2) )
{
fxvmm_mlist[fxvmm_mlistnum].type = FXVMM_MTSYSDATA;
_fxvmm_searchsd(mcb);
}
else
if( !strncmp( (mcb -> name) , "SC", 2 ) )
{
fxvmm_mlist[fxvmm_mlistnum].type=FXVMM_MTSYSCODE;
}
}
else
if( (mcb -> owner) > 0x0008 )
{
fxvmm_mlist[fxvmm_mlistnum].environment=_fxvmm_envseg(mcb);
fxvmm_mlist[fxvmm_mlistnum].type=FXVMM_MTAPP;
strncpy(fxvmm_mlist[fxvmm_mlistnum].name, mcb->name, 8);
strupr(fxvmm_mlist[fxvmm_mlistnum].name);
}
}
}
/*
Build a list of MCB's
*/
void _fxvmm_make_mcblist( void )
{
unsigned int i, j;
FXVMM_MCBHEAD *cur_mcb;
unsigned char origlink;
memset( fxvmm_mlist, 0x00, sizeof(fxvmm_mlist) );
if( _fxvmm_check_ems() == ERROR )
return ;
if( _fxvmm_check_xms() == ERROR )
return ;
if( _fxvmm_check_umb() == ERROR )
return ;
asm mov ah,52h
asm int 21h
asm mov ax,es:[bx-2]
asm mov word ptr fxvmm_firstmcb[2],ax
asm mov word ptr fxvmm_firstmcb,0
if( fxvmm_umb_api_installed )
{
origlink = _fxvmm_get_umblink();
_fxvmm_set_umblink(1);
}
cur_mcb = (FXVMM_MCBHEAD *)MK_FP(fxvmm_firstmcb, 0);
(unsigned int)fxvmm_dos_api_free = coreleft();
while( ( fxvmm_mlistnum < FXVMM_MAXITEM ) && (cur_mcb->type != 'Z') )
{
_fxvmm_regmcb(cur_mcb);
cur_mcb=(FXVMM_MCBHEAD *)MK_FP(FP_SEG(cur_mcb) + cur_mcb->size + 1, 0);
++fxvmm_mlistnum;
}
_fxvmm_regmcb(cur_mcb);
cur_mcb=(FXVMM_MCBHEAD *)MK_FP(FP_SEG(cur_mcb) + cur_mcb->size + 1, 0);
++fxvmm_mlistnum;
if( fxvmm_umb_api_installed )
_fxvmm_set_umblink( origlink );
for( i = 0 ; i < fxvmm_mlistnum ; i++ )
if( (fxvmm_mlist[i].seg >= 0x9000) && (fxvmm_mlist[i].seg <= 0xB000) && (fxvmm_mlist[i].type == FXVMM_MTSYSCODE) )
{
fxvmm_umb_api_index=i;
break;
}
for( i = fxvmm_umb_api_index ; i < fxvmm_mlistnum ; i++ )
if( fxvmm_mlist[i].type == FXVMM_MTFREE )
{
fxvmm_umb_api_free+=fxvmm_mlist[i].size;
if( fxvmm_mlist[i].size > fxvmm_umb_api_large )
fxvmm_umb_api_large=fxvmm_mlist[i].size;
}
for( i = 0 ; i < fxvmm_mlistnum ; i++ )
{
if( fxvmm_mlist[i].type == FXVMM_MTAPP )
for( j = 0 ; j < fxvmm_mlistnum ; j++ )
if( ( fxvmm_mlist[i].seg != fxvmm_mlist[j].seg ) && (fxvmm_mlist[j].owner == fxvmm_mlist[i].seg+1))
{
strcpy(fxvmm_mlist[j].name, fxvmm_mlist[i].name);
fxvmm_mlist[j].type = (fxvmm_mlist[i].environment == fxvmm_mlist[j].seg+1) ? FXVMM_MTENV : FXVMM_MTDATA;
}
if( fxvmm_mlist[i].type != FXVMM_MTSYSDATA )
_fxvmm_search_vectors(&fxvmm_mlist[i]);
}
for( i = 0 ; i < fxvmm_mlistnum; i++ )
if( fxvmm_mlist[i].seg+1 == _psp )
{
fxvmm_mlist[i+1].size+= fxvmm_mlist[i].size + 16;
fxvmm_mlist[i].type = FXVMM_MTMAP;
for( j = 0 ; j < fxvmm_mlistnum; j++ )
if( fxvmm_mlist[j].seg+1 == fxvmm_mlist[i].environment )
{
if( j == (i-1) )
{
fxvmm_mlist[j].type = FXVMM_MTMAP;
}
else
{
fxvmm_mlist[j].type = FXVMM_MTFREE;
fxvmm_mlist[j].name[0] = '\0';
}
break;
}
break;
}
}
/*
Display DOS memory
*/
void _fxvmm_display_dosmem( void )
{
unsigned int i, j, pos;
unsigned char line[81];
_fxvmm_make_mcblist();
fprintf( stderr, "\n\rMCB Size Name Type");
fprintf( stderr, "\n\rÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ");
for( i = 0 ; i < fxvmm_mlistnum ; i++ )
if( fxvmm_mlist[i].type != FXVMM_MTMAP )
fprintf( stderr, "\n\r%04Xh %6lu %-9s %-4s", fxvmm_mlist[i].seg, fxvmm_mlist[i].size, fxvmm_mlist[i].name, fxvmm_system_typenames[fxvmm_mlist[i].type]);
}
/*
Display EMS memory
*/
void _fxvmm_display_emsmem( void )
{
unsigned int i;
unsigned char *line, numstr[20];
unsigned char handlename[9];
if( _fxvmm_check_ems() == ERROR )
return ;
if( !fxvmm_ems_api_installed )
fprintf( stderr, "\n\rNo EMS driver installed on this system");
else
{
fprintf( stderr, "\n\rEMS driver version : %1i.%1i" , fxvmm_ems_api_vermajor, fxvmm_ems_api_verminor );
fprintf( stderr, "\n\rEMS page frame : %s" , fxvmm_ems_api_frame );
fprintf( stderr, "\n\rTotal EMS memory : %lu bytes" , fxvmm_ems_api_size );
fprintf( stderr, "\n\rFree EMS memory : %lu" , fxvmm_ems_api_free );
fprintf( stderr, "\n\rTotal EMS handles : %u" , fxvmm_ems_api_totalhandle );
fprintf( stderr, "\n\rFree EMS handles : %u" , fxvmm_ems_api_freehandle );
fprintf( stderr, "\n\rHandle Pages Size Name ");
fprintf( stderr, "\n\rÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ");
for( i = 0 ; i < fxvmm_ems_api_usehandle ; i++ )
{
memset(handlename, 0, sizeof(handlename));
if( fxvmm_ems_api_vermajor >= 4 )
{
if( fxvmm_ems_api_handles[i].handle == 0 )
strcpy(handlename, "SYSTEM");
else
{
asm push di
_DX = fxvmm_ems_api_handles[i].handle;
_ES = FP_SEG( &handlename );
_DI = FP_OFF( &handlename );
asm mov ax,5300h
asm int 67h
asm pop di
}
strupr(handlename);
}
fprintf( stderr , "\n\r%-7u %-6u %-9lu %-9s",fxvmm_ems_api_handles[i].handle, fxvmm_ems_api_handles[i].pages,(unsigned long)fxvmm_ems_api_handles[i].pages * 16384L, handlename);
}
}
}
/*
Display XMS memory
*/
void _fxvmm_display_xmsmem( void )
{
unsigned int i;
unsigned char *line, numstr[20];
_fxvmm_make_mcblist();
if( fxvmm_xms_api_installed )
{
fprintf( stderr, "\n\rPlease wait, testing XMS memory ...");
memset(fxvmm_xms_api_handles, 0, sizeof(fxvmm_xms_api_handles));
fxvmm_xms_api_usehandle = 0 ;
for( i = 0 ; i < 65535 ; i++ )
{
asm mov ah,0Eh
_DX = i;
(*fxvmm_xmsdrv_apicall)();
asm or ax,ax
asm jnz _found
continue;
_found:
asm mov byte ptr fxvmm_xms_api_freehandle,bl
if( fxvmm_xms_api_usehandle < FXVMM_MAXHANDLES )
{
asm push di
_ES = FP_SEG( &fxvmm_xms_api_handles );
_DI = FP_OFF( &fxvmm_xms_api_handles );
asm mov ax,fxvmm_xms_api_usehandle
asm mov cl,3
asm shl ax,cl
asm add di,ax
asm mov ax,i
asm mov es:[di],ax
asm mov es:[di+2],dx
asm mov es:[di+6],bh
asm pop di
fxvmm_xms_api_handles[fxvmm_xms_api_usehandle].size *= 1024L;
fxvmm_xms_api_usehandle++;
}
}
}
if( !fxvmm_xms_api_installed )
fprintf( stderr, "\n\rNo XMS driver installed on this system");
else
{
fprintf( stderr, "\n\rXMS driver version : %u.%u" , fxvmm_xms_api_vermajor, fxvmm_xms_api_verminor );
fprintf( stderr, "\n\rHMA state : %s" , (fxvmm_xms_api_hma) ? "exists" : "does not exist" );
fprintf( stderr, "\n\rA20 line state : %s" , (fxvmm_xms_api_a20) ? "enabled" : "disabled" );
fprintf( stderr, "\n\rFree XMS memory : %lu" , fxvmm_xms_api_free );
fprintf( stderr, "\n\rLargest Free XMS block : %lu" , fxvmm_xms_api_largest );
fprintf( stderr, "\n\rFree XMS handles : %u" , fxvmm_xms_api_freehandle );
if( fxvmm_xms_api_usehandle )
{
fprintf( stderr, "\n\r");
fprintf( stderr, "\n\rBlock Handle Size Locks");
fprintf( stderr, "\n\rÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ");
for( i = 0 ; i < fxvmm_xms_api_usehandle ; i++ )
printf("\n\r%-6u %-7u %-9lu %-12u",i, fxvmm_xms_api_handles[i].handle, fxvmm_xms_api_handles[i].size,fxvmm_xms_api_handles[i].locks);
fprintf( stderr, "\n\rÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ");
}
if( fxvmm_umb_api_installed )
{
fprintf( stderr, "\n\rFree Upper Memory : %lu" , fxvmm_umb_api_free );
fprintf( stderr, "\n\rLargest Upper Block : %lu" , fxvmm_umb_api_large);
}
else
fprintf( stderr, "\n\rNo Upper Memory avalaible");
}
}
/*
Display Virtual memory
*/
void _fxvmm_display_vrtmem( void )
{
if( _fxvmm_check_vrt() == ERROR )
return ;
fprintf( stderr, "\n\r%lu bytes of Virtual Memory available" , fxvmm_vrt_api_free );
}
/*
Display ALL memory
*/
void _fxvmm_display_allmem( void )
{
fprintf(stderr,"\n\rAvailable DOS memory : %12lu bytes", fxvmm_dos_api_free );
fprintf(stderr,"\n\rAvailable EMS memory : %12lu bytes", fxvmm_ems_api_free );
fprintf(stderr,"\n\rAvailable XMS memory : %12lu bytes", fxvmm_xms_api_free );
fprintf(stderr,"\n\rAvailable Virtual memory : %12lu bytes", fxvmm_vrt_api_free );
fprintf(stderr,"\n\rÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +");
if( fxvmm_fxapi_active )
fprintf(stderr,"\n\rAvailable FXVMM memory : %12lu bytes" , (fxvmm_ems_api_free + fxvmm_xms_api_free + fxvmm_vrt_api_free + fxvmm_dos_api_free) );
else
fprintf(stderr,"\n\rAvailable FXVMM memory : NONE - not initialized");
}
/*
function to mark the applications stack.
notes: Make sure you use it as the first executable statement ... i.e.
#include <....>
.
.
.
static data
.
.
.
_fxvmm_markstack();
.
.
.
rest of program
.
.
.
note(2): the function will use the atexit() function to
hook it's sister-procedure (_fxvmm_exitstack()) to the
exit procedure.
*/
void _fxvmm_markstack( void )
{
fxvmm_stack_segment = _SS ;
fxvmm_stack_st_ptr = _SP ;
FP_SEG(fxvmm_stack_st_top) = fxvmm_stack_segment ;
FP_OFF(fxvmm_stack_st_top) = fxvmm_stack_st_ptr ;
FP_SEG(fxvmm_stack_st_bot) = fxvmm_stack_segment;
FP_OFF(fxvmm_stack_st_bot) = 0x0000u;
fxvmm_stack_prt = fxvmm_stack_st_bot;
while( fxvmm_stack_prt < fxvmm_stack_st_top )
*fxvmm_stack_prt++ = fxvmm_stack_mark;
atexit( _fxvmm_exitstack );
}
void _fxvmm_exitstack( void )
{
fxvmm_stack_prt = fxvmm_stack_st_bot;
while( *fxvmm_stack_prt++ == fxvmm_stack_mark )
fxvmm_stack_unused++;
fprintf( stderr , "\n\rFXúVM Manager -> %u bytes of unused stack detected\n\r", fxvmm_stack_unused );
}