/***********************************************************\
* BloCom vergleicht eine Folge von Blöcken zweier Disketten *
* Getestet mit Aztec C V3.6a                                *
* Programmiert 1989 von: Angela Schmidt, Neu-Ulm            *
* Compileraufruf: cc BloCom                                 *
*                 ln BloCom -lc                             *
\***********************************************************/

#include <exec/exec.h>
#include <devices/trackdisk.h>
#include <functions.h>
#include <stdio.h>

struct MsgPort  *diskport[2];
struct IOStdReq *diskreq[2];
int openerror[2];
unsigned char   *Buf[2];


ReadBlock (block, buffer, Unit)  /* Liest Block 'block' aus Drive 'Unit' in */
int Unit, block;                 /* Speicherbereich 'buffer'                */
unsigned char *buffer;
{
   diskreq[Unit]->io_Length  = TD_SECTOR;
   diskreq[Unit]->io_Data    = (APTR)buffer;
   diskreq[Unit]->io_Command = CMD_READ;
   diskreq[Unit]->io_Offset  = block*TD_SECTOR;
   DoIO (diskreq[Unit]);
}

Motor (Zustand, Unit)      /* Motor des Drives 'Unit' schalten          */
long Zustand;              /* Zustand = TRUE: AN - Zustand = FALSE: AUS */
int Unit;
{
   diskreq[Unit]->io_Length  = Zustand;
   diskreq[Unit]->io_Command = TD_MOTOR;
   DoIO (diskreq[Unit]);
}

Errorcheck (FNr, drive, blk)
int FNr, drive, blk;
{
   printf ("\nHoppla, ein Fehler beim Leseversuch DRIVE %d - BLOCK %d\n\n",drive,blk);
   switch (FNr)
   {
      case 21: puts ("Sorry, kein Sektor-Header");break;
      case 23: puts ("Falsche Sektor-Kennung");break;
      case 24: puts ("Header-Checksumme stimmt nicht!");break;
      case 25: puts ("Falsche Daten-Checksumme");break;
      case 26: puts ("Das sind aber keine 11 Sektoren pro Track!");break;
      case 27: puts ("Sektor-Header unlesbar");break;
      case 29: puts ("Eine Diskette brauche ich aber schon!!!");break;
      case 31: puts ("Wie wärs mit einer Speichererweiterung?");break;
      case 33: puts ("Was ist das für ein komisches Laufwerk???");break;
      case 34: puts ("Welcher unverschämte Task klaut mir da mein Laufwerk?");break;
      default: printf ("Fehlernummer: %d\n",FNr);
   }
}

cleanall (text)
char *text;
{
   if (!openerror[0]) Motor (FALSE,0);
   if (!openerror[1]) Motor (FALSE,1);
   cleanup (0);
   cleanup (1);
   if (text) puts(text);
   exit(0);
}

cleanup (Unit)              /* Aufräumen und Message ausgeben */
int Unit;
{
   if (!openerror[Unit]) CloseDevice (diskreq[Unit]);
   if (diskreq[Unit])    DeleteStdIO (diskreq[Unit]);
   if (diskport[Unit])   DeletePort (diskport[Unit]);
   if (Buf[Unit])        FreeMem (Buf[Unit], TD_SECTOR);
}


main ()
{
   char eingabe[1];
   int opt, Unit;
   int StartBlock, EndBlock;
   register int blk, i;
   char *help;

   printf ("%cc%c[1;4;33mBloCom%c[0m  (%c[33mBlo%c[31mck-%c[33mCom%c[31mparer%c[0m)\n\n",27,27,27,27,27,27,27,27);
   puts ("Programmiert 1989 von Angela Schmidt\n");
   puts ("Dieses Programm vergleicht beliebige Blöcke zweier Disketten in den");
   puts ("Drives 'DF0:' und 'DF1:'. Start- und Endblock können angeben werden.");
   puts ("Sie können entweder jedes Byte, das verschieden ist, ausgeben lassen");
   puts ("oder nur die Nummern der Blöcke, die verschieden sind.\n");
   puts ("Während des Vergleichs kann das Programm jederzeit mit <HELP> beendet werden.\n");

   do {
      printf ("Bytes (b) - Blocknummern (n) - Ende (e)  => ");
      scanf ("%1s",eingabe);
   } while (!(eingabe[0]=='b' || eingabe[0]=='n' || eingabe[0]=='e'));
   if (eingabe[0]=='b') opt=TRUE; else opt=FALSE;
   if (eingabe[0]=='e') exit (0);

   do {
      printf ("Startblock (0-1759) => ");
      scanf ("%d",&StartBlock);
   } while (StartBlock<0 || StartBlock>1759);

   do {
      printf ("Endblock   (0-1759) => ");
      scanf ("%d",&EndBlock);
   } while (EndBlock<0 || EndBlock>1759);

   if (StartBlock>EndBlock) exit (0);

   openerror[0]=TRUE; openerror[1]=TRUE;
   help=12577793;

   for (Unit=0; Unit<=1; Unit++)
   {
      Buf[Unit] = AllocMem (TD_SECTOR,MEMF_CHIP|MEMF_CLEAR);
      if (!Buf[Unit]) cleanall ("Kein Speicher");

      diskport[Unit] = CreatePort ("Angela.port",0L);
      if (!diskport[Unit]) cleanall ("CreatePort hat nicht funktioniert!");

      diskreq[Unit] = CreateStdIO (diskport[Unit]);
      if (!diskreq[Unit]) cleanall ("CreateStdIO hat nicht funktioniert!");

      openerror[Unit] = OpenDevice (TD_NAME,(LONG)Unit,diskreq[Unit],0L);
      if (openerror[Unit]) cleanall ("OpenDevice hat nicht funktioniert!");

      Motor (TRUE,Unit);
   }

   for (blk=StartBlock; blk<=EndBlock; blk++)
   {
      if (*help==65) cleanall ("Ok, ich hör' ja schon auf.");
      ReadBlock (blk, Buf[0], 0);
      if (diskreq[0]->io_Error != 0) {
         Errorcheck (diskreq[0]->io_Error,0,blk);
         cleanall("\nIch glaube, es ist besser, wenn ich aufhöre...");
      }
      ReadBlock (blk, Buf[1], 1);
      if (diskreq[1]->io_Error != 0) {
         Errorcheck (diskreq[1]->io_Error,1,blk);
         cleanall("\nIch glaube, es ist besser, wenn ich aufhöre...");
      }
      for (i=0; i<512; i++)
      {
         if (Buf[0][i]!=Buf[1][i])
         {
            if (opt)
            {
               printf ("Block %4d - Byte %3d | DF0: %2x = '%c%c' | DF1: %2x = '%c%c'\n",blk,i,Buf[0][i],Buf[0][i],15,Buf[1][i],Buf[1][i],15);
               if(*help==65) cleanall ("Ach, wie schade...");
            }
            else
            {
               i=512;
               printf ("Verschieden: Block %d\n",blk);
            }
         }
      }
   }
   cleanall("Diskettenvergleich erfolgreich beendet!");
}

