/* << MSC V5.1 >> [FM-TOWNS] ************************************************
*
*	EMSﾁｪｯｸ (MS-DOS汎用)
*	----------------------------------------------------------------------
*	All Rights Reserved, Copyright (C) Y.Hirata 1993.
*	Programmed by Y.Hirata ( NIFTY-ID: NAB03321  パオパオ )
*
*	NOTE: TAB=4
****************************************************************************/

#include <stdio.h>			/*  printf		*/
#include <stdlib.h>			/*  exit		*/
#include <string.h>			/*  str**		*/
#include <dos.h>			/*  intdosx		*/
#include "lib\define.h"		/*  定数宣言	*/
#include "lib\typedef.h"	/*  型宣言		*/
#include "lib\mem.h"		/*  _peek,_poke	*/

#define	INT_EMM				0x67				/*  EMMﾌｧﾝｸｼｮﾝ			*/
BYTE	EMMname[] = "EMMXXXX0" ;

extern void putcrlf( void ) ;

static void closehd( WORD hd )
/*===========================================================================
*	ﾊﾝﾄﾞﾙｸﾛｰｽﾞ
===========================================================================*/
{
	union	REGS	regs ;

	regs.h.ah = 0x3E ;							/*  ｸﾛｰｽﾞﾊﾝﾄﾞﾙ			*/
	regs.x.bx = hd ;
	intdos( &regs,&regs ) ;
}

static int openchk( void )
/*===========================================================================
*	EMMをﾌｧｲﾙﾊﾝﾄﾞﾙでﾁｪｯｸする.
*	< RET >	: ｴﾗｰｺｰﾄﾞを返す.
*				=0	EMMあり
*				=1	EMMなし
===========================================================================*/
{
	union	REGS	regs ;
	struct	SREGS	sregs ;
	WORD	hd ;

	regs.x.ax = 0x3D00 ;						/*  ｵｰﾌﾟﾝﾊﾝﾄﾞﾙ			*/
	regs.x.dx = _off( EMMname ) ;
	sregs.ds  = _seg( EMMname ) ;
	intdosx( &regs,&regs,&sregs ) ;
	if ( regs.x.cflag ) return 1 ;				/*  EMMなし				*/
	hd = regs.x.ax ;							/*  ﾌｧｲﾙﾊﾝﾄﾞﾙ			*/

	regs.x.bx = hd ;
	regs.x.ax = 0x4400 ;						/*  IOCTRLﾃﾞｰﾀ取得		*/
	intdos( &regs,&regs ) ;
	if ( regs.x.cflag ) {
		closehd( hd ) ;
		return 1 ;
	}
	if ( !(regs.h.dl & 0x80) ) {				/*  ﾌｧｲﾙ				*/
		closehd( hd ) ;
		return 1 ;
	}
	regs.x.ax = 0x4407 ;						/*  出力ｽﾃｰﾀｽﾁｪｯｸ		*/
	regs.x.bx = hd ;
	intdos( &regs,&regs ) ;
	if ( regs.x.cflag ) {
		closehd( hd ) ;
		return 1 ;
	}
	closehd( hd ) ;
	return regs.h.al == 0xFF ? 0 : 1 ;
}

static int vectchk( void )
/*===========================================================================
*	EMMをﾍﾞｸﾀｱﾄﾞﾚｽでﾁｪｯｸする.
*	< RET >	: ｴﾗｰｺｰﾄﾞを返す.
*				=0	EMMあり
*				=1	EMMなし
===========================================================================*/
{
	register int	cnt ;
	int		len=strlen( EMMname ) ;
	WORD	seg ;
	BYTE	name[9] ;

	seg = _peek( 0,INT_EMM*4+2 ) ;
	for ( cnt=0; cnt<8; cnt++ )
		name[cnt] = _peekb( seg,0x0A+cnt ) ;	/*  ﾃﾞﾊﾞｲｽ名			*/
	for ( cnt=7; cnt>0; cnt-- ) {
		if ( name[cnt] != ' ' && name[cnt] != '\t' ) {
			name[cnt+1] = '\0' ;
			break ;
		}
	}
	return strcmp( EMMname,name ) == 0 ? 0 : 1 ;
}

int emmdisp( void )
/*===========================================================================
*	拡張ﾒﾓﾘの使用状態を表示する.
===========================================================================*/
{
	union	REGS	regs ;
	struct	SREGS	sregs ;
	WORD	use ;
	DWORD	size ;
	static struct {
		WORD	EMM_HANDLE ;
		WORD	PAGE_ALLOC_TO_HANDLE ;
	} emmhd[255] ;
	BYTE	name[9] ;
	int		cnt ;

	if ( openchk() && vectchk() ) return 1 ;	/*  EMMなし				*/

	regs.h.ah = 0x40 ;							/*  ｽﾃｰﾀｽ取得			*/
	int86( INT_EMM,&regs,&regs ) ;
	if ( regs.h.ah ) return 1 ;					/*  使用不可			*/

	regs.h.ah = 0x46 ;							/*  EMMﾊﾞｰｼﾞｮﾝ取得		*/
	int86( INT_EMM,&regs,&regs ) ;
	putcrlf() ;
	printf( "Expanded Memory Version %d.%d",
										(regs.h.al>>4),(regs.h.al&0x0F) ) ;
	
	putcrlf() ;
	regs.h.ah = 0x41 ;						/*  ﾍﾟｰｼﾞﾌﾚｰﾑのｾｸﾞﾒﾝﾄ取得	*/
	int86( INT_EMM,&regs,&regs ) ;
	if ( regs.h.ah ) return 1 ;					/*  使用不可			*/
	printf( "handle page  K bytes  name     属性    " ) ;
	printf( " (EMS frame:%04Xh)",regs.x.bx ) ;
	putcrlf() ;
	printf( "------ ----- -------- -------- --------" ) ;
	putcrlf() ;

	regs.h.ah = 0x4D ;				/*  確保されている全ﾍﾟｰｼﾞ数配列取得	*/
	regs.x.di = _off( emmhd ) ;
	sregs.es  = _seg( emmhd ) ;
	int86x( INT_EMM,&regs,&regs,&sregs ) ;
	use = regs.x.bx ;							/*  有効な要素数		*/
	for ( cnt=0; cnt<use; cnt++ ) {
		regs.x.ax = 0x5300 ;					/*  ﾊﾝﾄﾞﾙ名取得			*/
		regs.x.dx = emmhd[cnt].EMM_HANDLE ;
		regs.x.di = _off( name ) ;
		sregs.es  = _seg( name ) ;
		int86x( INT_EMM,&regs,&regs,&sregs ) ;
		if ( !regs.h.ah ) {
			name[8] = '\0' ;
			size = (DWORD)emmhd[cnt].PAGE_ALLOC_TO_HANDLE << 4 ;
			printf( "%6u %5u %7ldK %-8s ",emmhd[cnt].EMM_HANDLE,
								emmhd[cnt].PAGE_ALLOC_TO_HANDLE,size,name ) ;
			regs.x.ax = 0x5200 ;				/*  ﾊﾝﾄﾞﾙ属性取得		*/
			regs.x.dx = emmhd[cnt].EMM_HANDLE ;
			int86( INT_EMM,&regs,&regs ) ;
			printf( regs.h.al ? "不揮発性" : "揮発性" ) ;
			putcrlf() ;
		}
	}

	regs.h.ah = 0x42 ;							/*  未使用ﾍﾟｰｼﾞ数取得	*/
	int86( INT_EMM,&regs,&regs ) ;
	size = (DWORD)regs.x.bx << 4 ;
	printf( "  free %5u %7ldK ",regs.x.bx,size ) ;
	putcrlf() ;
	size = (DWORD)regs.x.dx << 4 ;
	printf( " total %5u %7ldK ",regs.x.dx,size ) ;
	putcrlf() ;

	return 0 ;
}

/*	HISTORY
-----------------------------------------------------------------------------
*	1993.04.03 : CREATE
---------------------------------------------------------------------------*/
