/* << High C V1.4 >> **********************************************************
**
**	ドライブ( A: 〜 P: )の状態を取得するプログラムです。
**
**	< HISTORY >
**	1990.02.07 : CREATE
**	1991.04.23 : 清書
**
**	< note > : TABS = 4
**
**	Programmed by Y.Hirata ( Nifty ID : NAB03321 )
**
******************************************************************************/

#include <dos.h>
#include <stdio.h>
#include <msdos.cf>
#include "hc.h"

/***************************  デバイス番号の取得  ****************************/
uchar DRV_devno( uchar drvno, uchar *drive_type, uchar *drive_no )
/*=============================================================================
**	< INPUT  > : drvno [BYTE] - ドライブ番号 ( 0 〜 15 )
**-----------------------------------------------------------------------------
**	< OUTPUT > : *drive_type [BYTE] - ドライブ種別
**									= 00H - 1MBフロッピィディスク
**									= 02H - ハードディスク
**									= 03H - RAM ディスク
**									= 05H - ROM
**									= FFH - 未登録
**			   : *drive_no   [BYTE] - 物理ドライブ番号
**-----------------------------------------------------------------------------
**	< RETURN > : デバイス番号
**			     = 0 の場合は、エラー
**				  エラーはドライブ番号の誤りまたはドライブ種別が不明の時です。
**
**	デバイス番号
**	_7_6_5_4_3_2_1_0_
**	| | | | | | | | |
**	~~~~~~~~~~~~~~~~~
**	        |-------| : ドライブ番号 ( 0 〜 15 ), HD の場合は、ユニット番号！
**	|-------| : デバイス
**				FPD = 0010 <02H>
**				HD  = 1011 <0BH>
**				RAM = 0100 <04H> : ﾄﾞﾗｲﾌﾞ番号は 0
**				ROM = 0100 <04H> : ﾄﾞﾗｲﾌﾞ番号は 2
=============================================================================*/
{
	int		adrs ;
	uchar	devno ;

	static uchar	getsysflg = FALSE ;
	static uchar	sysinf[200] ;

	devno = 0 ;
	if ( drvno > 15 )
		return( FALSE ) ;

	if ( !getsysflg ) {
		SYS_getinf( sysinf ) ;
		getsysflg = TRUE ;
	}

	adrs = drvno * 2 + 48 ;
	*drive_type = sysinf[adrs] ;
	*drive_no = sysinf[adrs+1] ;
	if ( *drive_type == DRV_FD ) {						/*  FD	*/
		devno = DEV_FD | *drive_no ;
	} else if ( *drive_type == DRV_HD ) {				/*  HD  */
		devno = DEV_HD | (*drive_no >> 4) ;
	} else if ( *drive_type == DRV_RAM ) {				/*  RAM	*/
		devno = DEV_RAM ;
	} else if ( *drive_type == DRV_ROM ) {				/*  ROM	*/
		devno = DEV_ROM ;
	} else {											/*  ???	*/
		devno = FALSE ;
	}

	return( devno ) ;
}

/********************  ドライブステータス情報の取り出し  *********************/
uchar DRV_status( uchar drvno )
/*=============================================================================
**	< INPUT  > : drvno [BYTE] - ドライブ番号 ( 0 〜 15 )
**	< OUTPUT > : なし
**	< RETURN > : ドライブ情報... = 0FFH ならば エラー( ドライブ指定ミス )
**											→ ドライブが未登録又は使用不可
**
**	_7_6_5_4_3_2_1_0_
**	| | | | | | | | |
**	~~~~~~~~~~~~~~~~~
**	|-------| : ドライブ種別
**				FD  = 0H
**				HD  = 2H
**				RAM = 3H
**				ROM = 5H
**
**			|-------| : ドライブ状態
**			       * ...Drive Ready ?    =0 <ready>  =1 <NOTready>
**			     * .....Write Protect ?  =0 <OFF>    =1 <ON>
**			   * .......Single Drive ?   =0 <NO>     =1 <YES>
**			 * .........記録密度         =0 倍密度   =1 単密度
=============================================================================*/
{
	union	REGS	regs ;
	uchar	devno, drive_type, drive_no, retinf, single ;

	if ( drvno > 15 ) {
/*		printf("Drive No.(%d) ERROR\n",drvno) ;		*/
		return( 0xff ) ;
	}

	if ( drvno == 1 ) {
		single = DRV_single() ;
	} else {
		single = FALSE ;
	}

	devno  = DRV_devno( drvno,&drive_type,&drive_no ) ;

	switch ( drive_type ) {
	case DRV_RAM :
		retinf = DRV_RAM ;
		retinf <<= 4 ;
		return( retinf ) ;
	case DRV_ROM :
		retinf = DRV_ROM ;
		retinf <<= 4 ;
		retinf |= 0x02 ;
		return( retinf ) ;
	case DRV_FD :
	case DRV_HD :
		break ;
	default :
		return( DEV_ERR ) ;
	}
	
	regs.h.ah = 0x02 ;
	regs.h.al = devno ;
	regs.h.ch = 0 ;

	int86(0x93,&regs,&regs) ;

	retinf = DRV_FD ;
	if ( drive_type == DRV_FD ) {			/*  FD	*/
		if ( (regs.h.dl & 0x80) == 0x80 )	/*  単密度？	*/
			retinf |= 0x08 ;
		if ( (regs.h.dl & 0x02) == 0x02 )	/*  書き込み保護？	*/
			retinf |= 0x02 ;
		if ( (regs.h.dl & 0x01) == 0x01 )	/*  NOT READY ？	*/
			retinf |= 0x01 ;
		if ( single && drvno == 1 )			/*  SINGLE DRIVE MODE ?	*/
			retinf |= 0x05 ;
		if ( regs.h.ah )					/*  エラー	*/
			retinf |= 0x01 ;
	} else if ( drive_type == DRV_HD ) {	/*  HD	*/
		retinf |= (DRV_HD << 4) ;
		if ( regs.h.ah )					/*  エラー	*/
			retinf |= 0x01 ;
	} else if ( regs.h.ah ) {				/*  エラー	*/
		retinf = 0xff ;
	} else {
		retinf |= 0xf1 ;					/*  ?????	*/
	}
	return( retinf ) ;
}

