/**************************************************/
/*                                                */
/*               MINIMON von A. Wolf              */
/*                                                */
/*       April 1988,    Modul  <minimon.c>        */
/*                                                */
/**************************************************/

#include <exec/types.h>
#include <graphics/display.h>
#include <graphics/gfxbase.h>
#include <graphics/text.h>
#include <graphics/view.h>
#include <graphics/layers.h>
#include <graphics/rastport.h>
#include <devices/timer.h>
#include <intuition/intuitionbase.h>

#include <gadget.h>

#define MIN  0L
#define MAX  0xFFFFC7L
#define FEHL 0x1000000

struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
struct Window *window;
struct Screen *screen;
struct RastPort *rastport;
struct IntuiMessage *mess,*GetMsg();

char hex[]="0123456789abcdef";
char *text_ptr,text[34];
char *suchstr,*nach[10],*schrift[7];
int  gadgid,faktor,autoflag=0;
int  linien[] = {
   10,108,90,108,18,116,98,108,177,108,106,116,
   185,108,264,108,213,116,272,108,351,108,300,116,
   185,135,264,135,197,143,272,135,351,135,296,143,
   10,135,177,135,43,143
};
long temp,adresse,start,ende,inhalt,*spei;
long ashex();

main()
{
   ULONG class;

   nach[0]      = "                   ";
   nach[1]      = "Fehleingabe!       ";
   nach[2]      = "Nicht gefunden!    ";
   nach[3]      = "Suchen...          ";
   nach[4]      = "Guten Tag!         ";
   nach[5]      = "Automatik...       ";
   nach[6]      = "Auf Wiedersehen!   ";
   nach[7]      = "Ungerade Adresse!  ";
   nach[8]      = "Untere Grenze!     ";
   nach[9]      = "Obere Grenze!      ";

   schrift[0]   = "Anzeigen";
   schrift[1]   = "Suchtext";
   schrift[2]   = "von";
   schrift[3]   = "bis";
   schrift[4]   = "Adresse";
   schrift[5]   = "Wert";
   schrift[6]   = "MINIMON sagt:";

   text_ptr     = &text[0];
   suchstr      = TexString1.Buffer;
   start        = ashex(TexString2.Buffer);
   ende         = ashex(TexString3.Buffer);
   adresse      = ashex(TexString0.Buffer);

   setup();

   RefreshGadgets(&tex_gad5,window,NULL);
   lese(adresse,text_ptr);

   for(;;)
   {
      /**          ggf. Automodus setzen         **/

      if(autoflag)
      {
         lese(adresse,text_ptr);
         adresse = adresse + (8*faktor);
         if( adresse > MAX )
         {
            adresse = MAX;
            nachricht(9);
         }
         if( adresse < MIN )
         {
            adresse = MIN;
            nachricht(8);
         }
      }

      /**      Message holen und auswerten       **/

      if( mess = GetMsg(window->UserPort) )
      {
         class = mess->Class;
         ReplyMsg(mess);
         if(class == CLOSEWINDOW)
         {
            nachricht(6);
            Delay(50L);
            CloseWindow(window);
            CloseLibrary(IntuitionBase);
            CloseLibrary(GfxBase);
            exit(0);
         }

         if(class == GADGETUP)
         {
            gad(mess);
         }
      }
   }
}

/**        Gadget-ID holen und auswerten         **/ 

gad(mess)

struct IntuiMessage *mess;
{
   struct Gadget *gad;

   gad      = (struct Gadget *)mess->IAddress;
   gadgid   = gad->GadgetID;
   autoflag = NULL;
   nachricht(0);

   switch (gadgid)
   {
      /**           Gadget "Anzeigen"            **/

      case 0:  temp = ashex(TexString0.Buffer);
               if( temp == FEHL )
               {
                  nachricht(1);
               }
               else
               {
                  adresse=temp;
                  lese(adresse,text_ptr);
               }
               break;

      /**           Gadget "Suchstring"          **/

      case 1:  suchstr = TexString1.Buffer;
               break;

      /**      Gadgets "von","bis","Suchen"      **/

      case 2:  temp = ashex(TexString2.Buffer);
               if( temp == FEHL )  { nachricht(1); }
               else                { start = temp; }
               break;
      case 3:  temp = ashex(TexString3.Buffer);
               if( temp == FEHL )  { nachricht(1); }
               else                { ende = temp;  }
               break;
      case 4:  if( ende < start )
               {
                  nachricht(1);
                  break;
               }
               nachricht(3);
               temp = such(suchstr);
               if( temp == FEHL ) 
               {
                  nachricht(2);
               }
               else
               {
                  adresse = temp;
                  lese(adresse,text_ptr);
                  nachricht(0);
               }
               break;

      /**        Gadgets "+","++","-","--"       **/

      case 6:  adresse = adresse+8;
               if( adresse > MAX )
               {
                  adresse = MAX;
                  nachricht(9);
               }
               lese(adresse,text_ptr);
               break;
      case 7:  adresse = adresse-8;
               if( adresse < MIN )
               {
                  adresse = MIN;
                  nachricht(8);
               }
               lese(adresse,text_ptr);
               break;
      case 8:  adresse = adresse + 64;
               if( adresse > MAX )
               {
                  adresse = MAX;
                  nachricht(9);
               }
               lese(adresse,text_ptr);
               break;
      case 9:  adresse = adresse - 64;
               if( adresse < MIN )
               {
                  adresse = MIN;
                  nachricht(8);
               }
               lese(adresse,text_ptr);
               break;

      /**             Gadgets "Auto"             **/

      case 10: autoflag = 1;
               faktor   = 1;
               nachricht(5);
               break;
      case 11: autoflag = 1;
               faktor   =-1;
               nachricht(5);
               break;

      /**  Gadgets "Adresse","Wert","Schreiben"  **/

      case 12: temp = ashex(TexString4.Buffer);
               if( temp == FEHL )  { nachricht(1); }
               else                { spei = temp;  }
               break;
      case 13: temp = ashex(TexString5.Buffer);
               if( temp == FEHL )  { nachricht(1); }
               else                { inhalt = temp;}
               break;
      case 14: schreib();
               break;
      default: break;
   }
   return();
}

/**        Speicher lesen und darstellen         **/
/**                                              **/
/**  adr       = Adresse, ab der gelesen wird    **/
/**  text_ptr  = String, der die Adresse und den **/
/**              Inhalt enthaelt                 **/
/**  text_ptr2 = String der die druckbaren Zei-  **/
/**              chen bzw. "." enthaelt          **/

lese(adr,text_ptr)
ULONG adr;
char *text_ptr;
{
   char *inhalt,*text_ptr2,ascii[8];
   int  spalte,zeile;

   text_ptr2 = &ascii[0];

   for(zeile=0;zeile<8;zeile++)
   {
      hexas(adr,text_ptr,8);
      inhalt        = adr;
      text_ptr      = text_ptr+8;
      *text_ptr     = 0x20;
      *(text_ptr+1) = 0x20;
      text_ptr      = text_ptr+2;

      for(spalte=0;spalte<8;spalte++)
      {
         hexas(*inhalt,text_ptr,2);
         if(((*inhalt) >= 0x20) && ((*inhalt) <= 0x7E))
         {
            *(text_ptr2+spalte) = *inhalt;
         }
         else
         {
            *(text_ptr2+spalte) = 0x2E;
         }
         inhalt     = inhalt+1;
         text_ptr   = text_ptr+2;
         *text_ptr  = 0x20;
         text_ptr++;
      }

      text_ptr = &text[0];
      Move(rastport,16,24+(zeile*9));
      Text(rastport,text_ptr,34);
      Move(rastport,294,24+(zeile*9));
      Text(rastport,text_ptr2,8);
      adr=adr+8;
   }
   return();
}

/**        Langwert in Speicher schreiben        **/
/**                                              **/
/**  spei   = Adresse, in die geschrieben wird   **/
/**  inhalt = Wert, der in Adresse geschrieben   **/
/**           wird                               **/
/**  dummy  = zur Ueberpruefung auf ungerade     **/
/**           Adresse                            **/

schreib()
{
   long dummy;
   dummy = spei;

   if(dummy & 0x0001)
   {
      nachricht(7);
      return();
   }
   *spei = (long)inhalt;
   lese(adresse,text_ptr);
   return();
}

/**           String im Speicher suchen          **/
/**                                              **/
/**  suchstr   = String, nach dem gesucht wird   **/
/**  start     = "von"                           **/
/**  ende      = "bis"                           **/
/**  text_ptr3 = Zwischenspeicher                **/
/**  erf       = Erfolg j/n                      **/

such(suchstr)
char *suchstr;
{

   char *text_ptr2,*text_ptr3,text3[8];
   int erf,anz;

   text_ptr3 = &text3[0];
   text_ptr2 = start;

   while(text_ptr2 < ende)
   {
      anz = strlen(suchstr);
      strncpy(text_ptr3,text_ptr2,anz);
      erf = strncmp(suchstr,text_ptr3,anz);
      if(erf == 0)
      {
         return(text_ptr2);
      }
      text_ptr2 = text_ptr2 + 1;
   }
   return(FEHL);
}

/**                  Bildaufbau                  **/

setup()
{
   int offs,i=0;

   GfxBase       = (struct GfxBase *)
                    OpenLibrary("graphics.library",0);
   IntuitionBase = (struct IntuitionBase *)
                    OpenLibrary("intuition.library",0);
   window        = (struct Window *)
                    OpenWindow(&meinwin);
   rastport      = window->RPort;
   screen        = window->WScreen;

   Move(rastport,10,15);
   Draw(rastport,366,15);
   Draw(rastport,366,91);
   Draw(rastport,10,91);
   Draw(rastport,10,15);

   Move(rastport,10,122);
   Draw(rastport,177,122);
   Draw(rastport,177,145);
   Draw(rastport,10,145);
   Draw(rastport,10,122);

   for(offs=0;offs<42;offs=offs+6)
   {
      Move(rastport,linien[offs],linien[offs+1]);
      Draw(rastport,linien[offs+2],linien[offs+3]);
      Move(rastport,linien[offs+4],linien[offs+5]);
      Text(rastport,schrift[i],strlen(schrift[i]));
      i++;
   }
   SetAPen(rastport,1);
   nachricht(4);
   return();
}

/**              Nachricht ausgeben              **/

nachricht(num)
int num;
{
   Move(rastport,18,132);
   Text(rastport,nach[num],19);
   return();
}

/**        Hexzahl in String konvertieren        **/
/**                                              **/
/**  zahl     = Hexzahl, die konvertiert wird    **/
/**  text_ptr = String, in den konvertiert wird  **/
/**  anz      = signifikante Stellen             **/

hexas(zahl,text_ptr,anz)

ULONG zahl;
char *text_ptr;
int anz;
{
   int bit,ziff,temp,faktor;
   int i=0;

   for(bit=(anz-1)*4;bit>-4;bit=bit-4)
   {
      temp = ((zahl >> bit) & 0x000f);
      if(temp > 9) { faktor = 55; }
      else         { faktor = 48; }
      ziff = temp + faktor;
      *(text_ptr+i) = ziff;
      i++;
   }
   return();
}

/**        String in Hexzahl konvertieren        **/
/**                                              **/
/**  ptr = String, der konvertiert wird          **/

ashex(ptr)
char *ptr;
{
   int stell,lae,i;
   ULONG adr=0;

   lae = strlen(ptr);

   for (stell=0;stell<lae;stell++)
   {
      for(i=0;i<16;i++)
      {
         if(!(strchr(hex,*(ptr+stell))))
         {
            return(FEHL);
         }
         if(hex[i] == *(ptr+stell))
         adr=adr+(i*(pow(16,lae-stell-1)));
      }
   }
   if(   ((adr > MAX) || (adr < MIN))
      && !(gadgid==13) )
   {
      return(FEHL);
   }
   return(adr);
}

/**             Schluss <minimon.c>              **/

