/* DROPZONE version 1.2 for z80 emulator
Compile with BDSC
  cc dropzone
  clink dropzone   */

/* Changes
 made it required to supply drive.
 fixed lastdrive to be p instead of z
*/

#include <stdio.h>
/*
0x80:	Dropzone File Count/Set Current File
	(write zero to reset DropZone)
0x81:	
0x82: 	DropZone Windows File Name byte (read until NULL)
0x83: 	DropZone CPM File Name byte  (read until NULL)
0x84: 	DropZone FileSize byte 0 LL (little End-ian)
0x85: 	DropZone FileSize byte 1 LH
0x86:	DropZone FileSize byte 2 HL
0x87: 	DropZone FileSize byte 3 HH
0x88: 	DropZone Status Input/Control 0=NOT EOF, 1=EOF 
	(note - status is reverse of DLOAD)
0x89: 	DropZone Data Input
*/

main(argc,argv)
int argc;
char **argv;
{

int Function;
int i;
int f;
int Usage;
int FileCnt;
int DZFileCnt;
int RTN;

char BufDriveSpec[5];      /* only used when listing and is NULL*/
char BufDZCpmFileName[20]; /* "00:01234567.012"    */
char BufDZWinFileName[1024]; 
char BufNewFileName[20];   /* "00/x:01234567.012"  */

char *DZCpmFileName;     
char *DZWinFileName;
char *NewFileName;
char *DriveSpec;

char *tempArg;

unsigned DZRecords;
unsigned DZBytes;
unsigned DZhigh;
unsigned DZlow;

DZCpmFileName=BufDZCpmFileName;
DZWinFileName=BufDZWinFileName;
NewFileName=BufNewFileName;
DriveSpec=BufDriveSpec;

DZCpmFileName[0]=0;
DZWinFileName[0]=0;
NewFileName[0]=0;
DriveSpec[0]=0;

Usage=0;
Function=0;

if(argc > 2) Usage++;

if (argc == 2)
	{
	tempArg=argv[1];
/*	i=0; while (tempArg[i]!=0){ tempArg[i]=toupper(tempArg[i]); i++;} */
	if ( strcmp(tempArg,"RESET")==0 ){outp(0x80,0); exit();}
	if ( strcmp(tempArg,"LIST")==0 ){Function=1;tempArg[0]=0;}
	switch (Function)
	  {
	   case 0:
 		DriveSpec=argv[1];
		if ( (DriveSpec[0] < 'A') || (DriveSpec[0] > 'P') ) Usage++;
		if ( (DriveSpec[1] != ':') ) Usage++;
		if ( strlen(DriveSpec) != 2 ) Usage++;
		break;
	   case 1:
		break;
	  }
	}
else Usage++;

printf("\n Dropzone Version 1.2 for CPM/MPM on Z80 Emulator\n");

DZFileCnt=GetDZFileCnt();

if (DZFileCnt==0)
	{
	printf("\n  Drop Zone is Empty\n");
	printf("\n  Drag some files from Explorer to the Drop Zone before running DropZone\n");
	Usage++;
	}

if (Usage != 0)	
	{	
	printf("\n   Usage: DropZone <Drive>: | RESET | LIST <cr>\n");
	printf("\n      can not use default for drive\n");
	exit();
	}

FileCnt=0;

for ( f=1 ; f<=DZFileCnt ; f++ )
{
	SetDZFile(f);

	DZlow=inp(0x84)+(inp(0x85)*256);
	DZhigh=inp(0x86)+(inp(0x87)*256);
	DZRecords=( ( (inp(0x86)*256) +  inp(0x85)  ) *2 )  +  (inp(0x84)/128);
	DZBytes=inp(0x84) & 127;

	GetDZCpmFileName(DZCpmFileName);
	GetDZWinFileName(DZWinFileName);

	NewFileName[0]=DZCpmFileName[0];
	NewFileName[1]=DZCpmFileName[1];
	NewFileName[2]='/';
	NewFileName[3]=0;
	strcat(NewFileName,DriveSpec);
	strcat(NewFileName,&DZCpmFileName[3]);
	i=0; while ( (NewFileName[i]!=' ') && (NewFileName[i]!='.') ) i++;
	NewFileName[i]=0;
	strcat(NewFileName,&DZCpmFileName[11]);

	switch (Function)
	{
	   case 0:
		printf("\nProcessing File - %s\n",NewFileName);
		printf(" %s\n",DZWinFileName);
		if (DZlow != 0) DZhigh++;
		if (DZhigh > 128)
		{
			printf("  File greater than 8MB - skipping...\n");
		}
		else
		{
			printf("  %u records + %u bytes\n",DZRecords,DZBytes);
			RTN=DloadFile(NewFileName);
			switch (RTN)
			{ 
			case 0:
				FileCnt++;
				break;
			case -1:
				printf("Download error: %s n",errmsg(errno()));
				break;
			}
		}
		break;
	   case 1:
		printf("Listing File - %s\n",NewFileName);
		printf(" %s\n",DZWinFileName);
		if (DZhigh > 128)
		{
			printf("  File greater than 8MB\n");
		}
		else
		{
			printf("  %u records + %u bytes\n",DZRecords,DZBytes);
		}
		FileCnt++;
		break;
	}
}

switch (Function)
{
   case 0:
	printf("\nDone - %d Files Written",FileCnt);
	printf("\n       %d Files Skipped\n",DZFileCnt-FileCnt);
	outp(0x80,0);  /* RESET the Drop Zone */
	break;
   case 1:
	printf("\nDone - %d Files Listed\n",FileCnt);
	break;
}

exit();

}

SetDZFile(FileNo)
int FileNo;
{
outp(0x80,FileNo);
}

GetDZFileCnt()
{
return(inp(0x80));
}

GetDZCpmFileName(NewFileName)
char *NewFileName;
{
int i;
int InByte;
i=0;

do{
  InByte=inp(0x83);
  NewFileName[i]=InByte;
  i++;
}while (InByte!=0);

return(i);
}

GetDZWinFileName(NewFileName)
char *NewFileName;
{
int i;
int InByte;
i=0;

do{
  InByte=inp(0x82);
  NewFileName[i]=InByte;
  i++;
}while (InByte!=0);

return(i);
}
 

DloadFile(CPMfileName)
char *CPMfileName;
{
FILE *fp;
int cntz;
int InByte;
int fd;
int RecCnt;

if( (fd = open(CPMfileName,0))!=-1 )
{
   close(fd);
   printf(" File Exists - Overwrite? (Y or N) - ");
   InByte=getchar();
   printf("\n");
   if ( (InByte != 'Y') && (InByte != 'y' ) ) return(-2);
}

if( (fp = fopen(CPMfileName,"wb"))==NULL ) 	
{
   printf("\nCan't open %s\n",CPMfileName);
   return(-1);
}
printf(" Downloading...");

cntz=0x80;
RecCnt=0;

outp(0x88,0xff); /* rewind NOT implememnted*/

while (inp(0x88)==0) /* NOT EOF*/
{
	InByte=inp(0x89);
	if (inp(0x88)==0) /* NOT EOF*/
	{
	 if (fputc(InByte,fp) == -1) return(-1);
	 cntz--;
	 if (cntz==0){ cntz=0x80; RecCnt++; }
	};
}
while (cntz !=0 && cntz !=0x80) 
{
 fputc(0x1a,fp); cntz--; 
 if (cntz==0)RecCnt++;
}

fclose(fp);

printf(" Finished\n%d Records Written\n",RecCnt);

return(0);
}