/*********************************************\
* Core of code for all CDx technical programs *
\*********************************************/

#include <exec/types.h>
#include <CDx.h>

struct   MsgPort        *MyPort;
struct   IOStdReq       *Req;
int      OpenError = 1;

int OpenCDx(drive)
int   drive;
{
   OpenError = 1;

   MyPort = (struct MsgPort *)CreatePort(0,0);
   if (!MyPort)
      return(-1);
   Req = (struct IOStdReq *)CreateStdIO(MyPort);
   if (!Req) {
      DeletePort(MyPort);
      return(-1);
   }

   OpenError = OpenDevice("cdx.device",drive,(struct IORequest *)Req,0);

   return(OpenError);
}


void CloseCDx(void)
{
   if (!OpenError)
      CloseDevice((struct IORequest *)Req);
   if (Req)
      DeleteStdIO(Req);
   if (MyPort)
      DeletePort(MyPort);
   OpenError = 1;
}

char  *ErrorStrings[] = {
   "unknown error",
   "no drive",
   "failed",
   "foreign drive",
   "in use",
   "no disc",
   "illegal",
   "stopped",
   "bad track number",
   "data track",
   "bad location",
   "bad length",
   "disc unreadable",
   "bad MSF value",
   "no data",
   "not supported"
};


void Cleanup(msg,code)
char  *msg;
int   code;
{
   int   index,retcode;

   if (msg)
      printf("%ls\n",msg);
   else if (code>0) {
      if ((code>=CDERR_ForeignDrive)&&(code<=CDERR_NotSupported))
         index = code - CDERR_ForeignDrive + 3;
      else if ((code>=CDERR_NoDrive)&&(code<=CDERR_Failed))
         index = code - CDERR_NoDrive + 1;
      else
         index = 0;
      printf("Error - %ls\n",ErrorStrings[index]);
   }

   CloseCDx();

   retcode = (msg || code)?10:0;
   exit(retcode);
}


int ParseParams(usage,argc,argv,drive,count,param1) /* VARARGS */
char  *usage,**argv;
int   argc,count,*drive,*param1;
{
   int   parse,rcvd,**parms;

   *drive = 1;       /* Default: drive 1 */

   parms = &param1;
   for (rcvd=0,parse=1;parse<argc;parse++) {        /* Scan all arguments */
      if (my_strnicmp(argv[parse],"DRIVE",5)==0) {  /* Spec'd drive? */
         parse++;
         if (parse >= argc) {
            printf("Error: no drive specified\n");
            exit(10);
         }
         *drive = my_atoi(argv[parse]);
         if ((*drive<1)||(*drive>8)) {
            printf("Error: drive must be 1-8\n");
            exit(10);
         }
      }
      else {
         if (rcvd<count) {                      /* Safe to keep this? */
            **parms = my_atoi(argv[parse]);
            parms++;
         }
         rcvd++;
      }
   }

   if ((rcvd!=count) ||                /* Incorrect number of params? */
    ((argc==2)&&(argv[1][0]=='?'))) {  /* (or requesting usage */
      if (usage) {
         printf("Usage: %ls\n",usage); /* Abort? */
         exit(10);
      }
      else {
         return(1);                    /* Return error */
      }
   }   

   (*drive)--;          /* 0-7 for cdx.device */

   return(0);           /* Okay */
}


int   my_atoi(str)
char  *str;
{
   register char  *p;
   int   v;

   p = str;
   v = 0;

   while (*p) {
      v *= 10;
      v += *p++ - '0';
   }

   return(v);
}


int my_strnicmp(str1,str2,len)
char  *str1,*str2;
int   len;
{
   register char  *s1,*s2;
   register char  c1,c2;

   s1 = str1;
   s2 = str2;
   while (len--) {
      c1 = *s1++;
      c2 = *s2++;
      if ((c1>='a')&&(c1<='z'))   /* toupper */
         c1 -= 32;
      if ((c2>='a')&&(c2<='z'))   /* toupper */
         c2 -= 32;
      if (c1 != c2)
         return(1);
   }
   return(0);
}
