/* << MSC V5.1 >> [FM-TOWNS] ************************************************
*
*	DPB情報取得(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 <jctype.h>			/*  iskanji		*/
#include "lib\define.h"		/*  定数宣言	*/
#include "lib\typedef.h"	/*  型宣言		*/
#include "lib\mem.h"		/*  _peek,_poke	*/

static WORD DPBoff ;
static WORD DPBseg ;

static void disp( WORD seg,WORD off )
/*===========================================================================
*	drive parameter block
===========================================================================*/
{
	WORD	nseg, noff ;
	WORD	dseg, doff ;
	WORD	data, dif ;

	printf( "Dr DPB.Addr  Byte Sct Res Clstr Bit FAT S/F " ) ;
	printf( "FDSc FScR R.Ent Dev.Addr  MDB AF\n" ) ;
	printf( "-- --------- ---- --- --- ----- --- --- --- " ) ;
	printf( "---- ---- ----- --------- --- --\n" ) ;
	dif = _osmajor > 3 ? 1 : 0 ;
	for ( ;; ) {
		if ( off == 0xFFFF ) break ;
		noff = (WORD)_peek( seg,off+0x18+dif ) ;
		nseg = (WORD)_peek( seg,off+0x1A+dif ) ;
		printf( "%c: ",_peekb( seg,off )+'A' ) ;	/*  drive			*/
		printf( "%04X:%04X ",seg,off ) ;			/*  DPB address		*/
		printf( "%4d ",_peek( seg,off+2 ) ) ;		/*  bytes/sector	*/
		printf( "%3d ",_peekb( seg,off+4 )+1 ) ;	/*  sectors/cluster	*/
		printf( "%3d ",_peek( seg,off+6 ) ) ;		/*  reserved sector	*/
		printf( "%5u ",_peek( seg,off+0x0D )-1 ) ;	/*  使用可cluster数	*/
/*
*		000,FF7〜FFFはﾘｻﾞｰﾌﾞ, 12bit時に使用可能な最大ｸﾗｽﾀ番号は FF6 である.
*		この場合, 使用可能なｸﾗｽﾀ数は, FF6-1 = FF5(4085) である.
*/
		if ( _peek( seg,off+0x0D ) < 0x0FF7 ) {		/*  12bit FAT		*/
			printf( " 12 " ) ;
		} else {									/*  16bit FAT		*/
			printf( " 16 " ) ;
		}
		printf( "%3d ",_peekb( seg,off+8 ) ) ;		/*  FAT数			*/
		if ( _osmajor < 4 ) {						/*  〜v3.x			*/
			data = (WORD)_peekb( seg,off+0x0F ) ;
		} else {									/*  v4.0〜			*/
			data = (WORD)_peek( seg,off+0x0F ) ;
		}
		printf( "%3d ",data ) ;						/*  sectors/FAT		*/
		printf( "%04X ",_peek( seg,off+0x0B ) ) ;	/*  first sector	*/
		data = (WORD)_peek( seg,off+0x10+dif ) ;
		printf( "%04X ",data ) ;					/*  1th sector root	*/
		printf( "%5d ",_peek( seg,off+0x09 ) ) ;	/*  root dir ｴﾝﾄﾘ数	*/
		doff = (WORD)_peek( seg,off+0x12+dif ) ;
		dseg = (WORD)_peek( seg,off+0x14+dif ) ;
		printf( "%04X:%04X ",dseg,doff ) ;			/*  device address	*/
		data = (WORD)_peekb( seg,off+0x16+dif ) ;
		printf( " %02X ",data ) ;					/*  media discript	*/
		data = (WORD)_peekb( seg,off+0x17+dif ) ;
		printf( "%02X ",data ) ;					/*  accessed		*/
		printf( "\n" ) ;
		off = noff ;
		seg = nseg ;
	}
}

void dpbdisp( void )
/*===========================================================================
*	DPB情報表示
===========================================================================*/
{
	union	REGS	regs ;
	struct	SREGS	sregs ;

	regs.h.ah = 0x52 ;							/*  ｼｽﾃﾑﾊﾟﾗﾒﾀﾃｰﾌﾞﾙ取得	*/
	intdosx( &regs,&regs,&sregs ) ;
	DPBoff = (WORD)_peek( sregs.es,regs.x.bx+0 ) ;
	DPBseg = (WORD)_peek( sregs.es,regs.x.bx+2 ) ;
#if 0
	printf( "DPBﾃｰﾌﾞﾙ=%04X:%04X\n",DPBseg,DPBoff ) ;
#endif

	printf( "\n" ) ;
	disp( DPBseg,DPBoff ) ;
}

static void appendix( void )
/*===========================================================================
*	解説表示
===========================================================================*/
{
	printf( "DPB(Drive Parameter Block)情報表示 Version 1.00 " ) ;
	printf( " (C) パオパオ 1993.\n" ) ;
	printf( "\n" ) ;
	printf( "Dr DPB.Addr  Byte Sct Res Clstr Bit FAT S/F " ) ;
	printf( "FDSc FScR R.Ent Dev.Addr  MDB AF\n" ) ;
	printf( "-- --------- ---- --- --- ----- --- --- --- " ) ;
	printf( "---- ---- ----- --------- --- --\n" ) ;
	printf( "Dr      : ドライブ名\n" ) ;
	printf( "DPB.addr: Drive Parameter Blockの格納アドレス\n" ) ;
	printf( "Byte    : バイト数／セクタ\n" ) ;
	printf( "Sct     : セクタ数／クラスタ\n" ) ;
	printf( "Res     : 予約セクタ数(FATの開始セクタ番号)\n" ) ;
	printf( "Clstr   : 使用可能なクラスタ数（総クラスタ数-10)\n" ) ;
	printf( "Bit     : FATのビット数／エントリ\n" ) ;
	printf( "FAT     : FAT数\n" ) ;
	printf( "S/F     : セクタ数／FAT\n" ) ;
	printf( "FDSc    : 最初のデータ開始セクタ番号" ) ;
	printf( "(First Data Sector on medium)\n" ) ;
	printf( "FScR    : ルートディレクトリの最初のセクタ番号" ) ;
	printf( "(First Sector of Root directory)\n" ) ;
	printf( "R.Ent   : ルートディレクトリでの最大エントリ数\n" ) ;
	printf( "Dev.addr: デバイスドライバのヘッダアドレス\n" ) ;
	printf( "MDB     : Media Discripter Byte (BPB識別用)\n" ) ;
	printf( "AF      : アクセスフラグ(00=アクセス済,FF=未アクセス)\n" ) ;
	exit( 1 ) ;
}

void main( int ac )
/*===========================================================================
*	ﾒｲﾝ
===========================================================================*/
{
	if ( ac > 1 ) appendix() ;
	dpbdisp() ;

	exit( 0 ) ;
}

