/*		FileCopy module			Search / SearchNext

    "FCSERCH.C"
*/

#include	"filecopy.os"
#include	"c:switch.os"
#include	"fcconst.h"
#include	"fcstruct.h"
#include	"fcdata.h"
#undef		debugP
#undef 		debug
/*=============================================================================
			HISTORY
	Last change:	14 March 1984		tpl
ver	0
rev	0
mod	c
patch	13


 mod
-----
  c7		November 11, 1983	tpl
	.Last series of patches: passing FCB again, drive -> 1=A, 2=B, 3=C...
	But OS uses (via SelDisk and CurDisk) 0=A, 1=B, 2=C, ...
	.Many variable name changes, cleanups.
	.Arrays of pointers for each drive's descriptors' working.

  c		November 1, 1983	tpl
	.Don't pass FCB, only a pointer to the name and drive.

  b		October 21, 1983	tpl
	.Call GetDMA upon exit from FirstDir and NextDir and put
	directory buffer contents there ala' CP/M.

  a		October 12, 1983	tpl
	.Begin coding FirstDir and NextDir for MSDOS under CP/M.
	They are to mimic the BDOS calls SearchFirst and SearchNext.
*/

/*=============================================================================
			CONSTANTS / DEFINITIONS
*/
/*=============================================================================
			VARIABLES and DATA STRUCTURES
*/
/*...........................................................................*/

/*page*/
/*=============================================================================
			ROUTINES	(and glutanous space monkeys)
*/
/*---------------------------------------------------------------------------*/

int
FirstDir( userFcb )
  CHAR	*userFcb;	/* userFcb is a pointer to an fcb.	*/
{
/* Find the first entry in the driectory matching the fcb passed.	*/
/* Return 0,1,2 or 3 for which entry in the frgnDirBuffer matches.		*/
/* Return 0xff if end of directory occurs.				*/

/* Tell NextDir start at first entry.*/
/* So set frgnDirInfo[ fcb drive ]->cur_entry to 0.	*/

#ifdef debugP
	printf("p..FirstDir\n");
	printf("  userFcb: %x    *userFcb: %x\n", userFcb, *userFcb);
	ShowMsFcb( userFcb );
#endif

    if ( *userFcb == 0xff)
	/* Then extended ms fcb.	*/
    {
	if ( *(userFcb + 7) == 0)	/* Then use curDisk. */
	    frgnDirInfo[ CurDisk() ]->curEntry = 0;
	else
	    frgnDirInfo[ *(userFcb + 7) - 1 ]->curEntry = 0;
    }
    else
	/* Else standard ms fcb.	*/
    {
	if ( *userFcb == 0)	/* Then use curDisk. */
	    frgnDirInfo[ CurDisk() ]->curEntry = 0;
	else
	frgnDirInfo[ *userFcb - 1 ]->curEntry = 0;
    }

    return( NextDir( userFcb ) );

}/*FirstDir*/

/*page*/
/*---------------------------------------------------------------------------*/

int NextDir( userFcb )
CHAR	*userFcb;	/* userFcb is a pointer an fcb.	*/

/* Keep reading dir records and comparing until match is found or end of
	directory is found.
   If match, return 0, 1, 2, or 3  giving the entry number in frgnDirBuffer.
   If no match, return ENDdirMS.
*/

{
CHAR	numChars;
CHAR	cur_disk, drive, match, i, *nameInDir;
int	entryNum; 
struct ms_fcb		*fcb;		/* Standard MSDOS fcb.		*/
struct ms_fcb_ex	*fcb_ex;	/* Extended MSDOS fcb.	*/
struct ms_dir_info		*curDir;

#ifdef debugP
	printf("p..NextDir\n");
	ShowMsFcb( userFcb );
#endif

	if ( *userFcb == 0xff ) { /* Then extended fcb.	*/
		fcb_ex = userFcb;
		fcb = userFcb + 7;
		}
	else {		/* else standard MSDOS fcb.	*/
		fcb = userFcb;
		fcb_ex = NULL;
 		}

#ifdef debug
	printf("  fcb_ex: %x hex    fcb: %x hex    userFcb: %x hex\n",
		  fcb_ex,	    fcb,	   userFcb);
#endif

	drive = cur_disk = CurDisk();
	if ( fcb->drive != 0)	/* if = 0 use curDisk.		*/ {
		drive = fcb->drive -1;	/* So 0=A, 1=B, 2=C, ...	*/
		SelDisk( drive );
		}
	curDir = frgnDirInfo [drive];
	while ( (entryNum = curDir->curEntry)
		!= curDir->endEntry ) {
		/* while not end of directory */
		if ( (entryNum 
			% (frgn_BPB [drive]->BytesInSector 
			/ sizeof (struct ms_dir_entry))) 
				== 0)/* Read new bufferfull */ {
#ifdef debug
		printf( "  entryNum: %03d decimal\n", entryNum);
#endif
		if ( entryNum == 0 ) { /* If search from dir start, init.   */
	    	/* Init track/sector to beginning of directory. */
			curDir->curTrack = 
				curDir->begTrack;
			curDir->curSector =
				curDir->begSector;
			}
		else { /* else advance to next 128 byte directory sector. */
			curDir->curTrack +=
					++curDir->curSector
					/ frgn_BPB[ drive ]->SectPerTrack;
			curDir->curSector =
					curDir->curSector
					% frgn_BPB[ drive ]->SectPerTrack;
			}

		ReadDirSector( drive );
		}

/* Get next dir entry to compare to passed template for match.	*/
	nameInDir = frgnDirBuffer[ entryNum 
		% (frgn_BPB [drive]->BytesInSector 
			/ sizeof (struct ms_dir_entry))].name;

#ifdef debug
	printf("nameInDir ---> ");
	if ( (nameInDir[1] < SPACE) || (nameInDir[1] >= DEL) )
		numChars = 2;
	else
		numChars = 11;

	for ( i=0; i<numChars; i++)
		if ( (nameInDir[i] < SPACE) || (nameInDir[i] >= DEL) )
			printf("<%x>",nameInDir[i]);
		else
			putchar( nameInDir[i] );
#endif

/* Check to see if current dir entry matches passed template.	*/
	match = TRUE;
	if (nameInDir[0] == ERASED || nameInDir[0] == 0)
		match = (fcb->name[0] == ERASED);
	else for ( i=0; i<LENname + LENtype; i++)
		if ((fcb->name[i] != nameInDir[i]) && (fcb->name[i] != '?')) {
			match = FALSE;
			break;		/* leave 'for' loop.	*/
			}
#ifdef debug
	printf ("\t%s\n", match ? "TRUE " : "FALSE");
#endif
	curDir->curEntry++; /* Must increment before returning.*/

	if ( match == TRUE ) {
		SetDMA (&frgnDirBuffer);
		SelDisk( cur_disk );	/* restore order. */
		return( entryNum 
			% (frgn_BPB [drive]->BytesInSector
				/ sizeof (struct ms_dir_entry)));
		}

	}/* While not end of directory */

	SelDisk( cur_disk );	/* restore order. */

	return(ENDdirMS);

	}/*NextDir*/

/*page*/
/*---------------------------------------------------------------------------*/

ReadDirSector( drive )
int drive;	/* Drive to read from. A = 0, B = 1,... */
{
	/* Read in 128 byte record of directory. Track and sector are already
	computed and stored in frgnDirInfo[ drive ]	*/

	int	save_DMA;

#ifdef debugP
	printf("p..ReadDirSector  .....  ");
#endif

	save_DMA = GetDMA();
#ifdef debug
	printf("    track: %x    sector: %x\n",
		frgnDirInfo[ drive ]->curTrack,
		frgnDirInfo[ drive ]->curSector);
#endif

	frgnRead (drive,  &frgnDirBuffer, frgnDirInfo [drive]->curTrack,
		frgnDirInfo [drive]->curSector);
	

	SetDMA( save_DMA );		/* Restore order. */

	}/*ReadDirSector*/
#ifdef debug
/*page*/
/*---------------------------------------------------------------------------*/

ShowMsFcb( userFcb )
  CHAR	*userFcb;
{
  struct ms_fcb		*fcb;		/* Standard MSDOS fcb.		*/
  struct ms_fcb_ex	*fcb_ex;	/* Extended MSDOS fcb.	*/
  CHAR	i;

    if ( *userFcb == 0xff )	/* Then extended fcb.	*/
    {
	fcb_ex = userFcb;
	fcb = userFcb + 7;
    }
    else		/* else standard MSDOS fcb.	*/
    {
	fcb = userFcb;
	fcb_ex = NULL;
    }
    printf("p..ShowMsFcb        ");
    if( fcb_ex == NULL )
	printf("standard\n");
    else
	printf("extended\n");

    printf(" drive: %x hex    name: ", fcb->drive);
    for ( i=0; i<LENname + LENtype; i++)
	putchar( fcb->name[i] );
    printf("\n");

}/*ShowMsFcb*/
#endif
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/

/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/

