/*---------------------------------------------------------------------*/
/*                         Bitmap - Analyser                           */
/*                                                                     */
/*                           JEA, 15-08-87                             */
/*---------------------------------------------------------------------*/
#include <exec/exec.h>
#include <devices/trackdisk.h>
#include <intuition/intuition.h>

#define ON 1L
#define OFF 0L
#define BLOCK_SIZE 128L
#define BM_FLAG BLOCK_SIZE-50L
#define BM_BLOCKS BLOCK_SIZE-49L

extern struct MsgPort *CreatePort();
extern struct IORequest *CreateExtIO();

struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;

struct TextAttr MyFont =
{
   "topaz.font",
   TOPAZ_EIGHTY,
   FS_NORMAL,
   FPF_ROMFONT,
};

struct NewScreen NewScreen =
{
   0,
   0,
   640,
   256,
   2,
   0, 1,
   HIRES|SPRITES,
   CUSTOMSCREEN,
   &MyFont,
   "- BitMap -",
   NULL,
   NULL,
};

/*---------------------------------------------------------------------*/
/*                      Motor ein- und ausschalten                     */
/*                                                                     */
/*                                                                     */
/*---------------------------------------------------------------------*/
Motor( diskreq, on )
struct IOExtTD *diskreq;
LONG on;
{
   diskreq->iotd_Req.io_Length = on;
   diskreq->iotd_Req.io_Command = TD_MOTOR;
   DoIO(diskreq);
   return(0);
}

/*---------------------------------------------------------------------*/
/*                   Block vom angegebenen Device lesen                */
/*                                                                     */
/*                                                                     */
/*---------------------------------------------------------------------*/
ReadBlock( diskreq, block, puffer, diskChangeCount )
struct IOExtTD *diskreq;
LONG block;
APTR puffer;
ULONG diskChangeCount;
{
   diskreq->iotd_Req.io_Length  = TD_SECTOR;
   diskreq->iotd_Req.io_Data    = puffer;
   diskreq->iotd_Req.io_Command = ETD_READ;
   diskreq->iotd_Count          = diskChangeCount;
   diskreq->iotd_Req.io_Offset  = block * TD_SECTOR;

   if(DoIO(diskreq))
      return(1);

   return(0);
}

/*---------------------------------------------------------------------*/
/*                   Bitmap-Block suchen und einlesen                  */
/*                                                                     */
/*                                                                     */
/*---------------------------------------------------------------------*/
LONG
ReadBitmap( diskreq, buf )
struct IOExtTD *diskreq;
LONG *buf;
{
ULONG diskChangeCount;


   diskreq->iotd_Req.io_Command = TD_CHANGENUM;
   DoIO(diskreq);
   diskChangeCount = diskreq->iotd_Req.io_Actual;

   Motor( diskreq, ON );
   ReadBlock( diskreq, 880L, buf, diskChangeCount );
   printf("Flag: %ld ,  Block#%ld \n", buf[BM_FLAG], buf[BM_BLOCKS] );
   if( buf[BM_FLAG] )
      ReadBlock( diskreq, buf[BM_BLOCKS], buf );
   Motor( diskreq, OFF );

   return( buf[BM_FLAG] );
}

/*---------------------------------------------------------------------*/
/*          Bitmap des angegebenen Devices grafisch darstellen         */
/*                                                                     */
/*                                                                     */
/*---------------------------------------------------------------------*/
DisplayBitmap( diskreq, Screen )
struct IOExtTD *diskreq;
struct Screen *Screen;
{
LONG *buf;
LONG x, y;
ULONG loop;

struct Window *Window;
struct NewWindow NewWindow;

ULONG MessageClass;
USHORT code;
LONG flag;
struct Message *GetMsg();
struct IntuiMessage *message;


   NewWindow.LeftEdge = 0;
   NewWindow.TopEdge = 0;
   NewWindow.Width = 640;
   NewWindow.Height = 160;
   NewWindow.DetailPen = 0;
   NewWindow.BlockPen = 1;
   NewWindow.Title = " Bitmap ";
   NewWindow.Flags = WINDOWCLOSE|SMART_REFRESH|ACTIVATE|
                     WINDOWDRAG|WINDOWDEPTH|
                     NOCAREREFRESH | GIMMEZEROZERO;
   NewWindow.IDCMPFlags = CLOSEWINDOW|DISKINSERTED|DISKREMOVED;
   NewWindow.Type = CUSTOMSCREEN;
   NewWindow.FirstGadget = NULL;
   NewWindow.CheckMark = NULL;
   NewWindow.Screen = Screen;
   NewWindow.BitMap = NULL;
   NewWindow.MinWidth = 640;
   NewWindow.MinHeight = 148;
   NewWindow.MaxWidth = 640;
   NewWindow.MaxHeight = 200;

   if(( Window = (struct Window*) OpenWindow( &NewWindow )) == NULL)
     exit( FALSE );

   SetAPen (Window->RPort, 1 );

   Move( Window->RPort, 500, 33 );
   Text( Window->RPort, "Seite 0", 7 );

   Move( Window->RPort, 500, 105 );
   Text( Window->RPort, "Seite 1", 7 );

   Move( Window->RPort, 0, 146 );
   Text( Window->RPort, "1", 1 );

   Move( Window->RPort, 466, 146 );
   Text( Window->RPort, "80", 2 );

   Move( Window->RPort, 480, 8 );
   Text( Window->RPort, "1. Sektor", 9 );

   Move( Window->RPort, 480, 64 );
   Text( Window->RPort, "11. Sektor", 10 );

   Move( Window->RPort, 480, 80 );
   Text( Window->RPort, "1. Sektor", 9 );

   Move( Window->RPort, 480, 136 );
   Text( Window->RPort, "11. Sektor", 10 );

   buf = (LONG*) AllocMem( 512L, MEMF_CHIP );
   ReadBitmap( diskreq, buf );
   buf[0] &= 0x3fffffffL;
   loop=30L;
   for( x=0; x<80; ++x ){
      for( y=0; y<22; ++y ){
         if( buf[loop/32] & (1L << (loop % 32)) )
            SetAPen (Window->RPort, 2 );
         else
            SetAPen (Window->RPort, 3 );
         if (y > 10)
            RectFill( Window->RPort, x*6, (y+1)*6, x*6+4, (y+1)*6+4 );
         else
            RectFill( Window->RPort, x*6, y*6, x*6+4, y*6+4 );
         ++loop;
      }
   }
   FreeMem( buf, 512L );

   Wait( 1<<Window->UserPort->mp_SigBit);
    flag = TRUE;
    do
    {
       if (message = (struct IntuiMessage *)GetMsg(Window->UserPort))  {
         MessageClass = message->Class;
         code = message->Code;
         ReplyMsg(message);
         switch (MessageClass) {
  
            case CLOSEWINDOW : flag = FALSE;
                               break;
            case DISKREMOVED :
                               Text( Window->RPort, "Disk Removed", 11);
                               break;
         }   /* Case */
       }  /* if */
    }
   while( flag );
   CloseWindow( Window );
}

/*---------------------------------------------------------------------*/
/*                   Benoetigte Libraries schliessen                   */
/*                                                                     */
/*                                                                     */
/*---------------------------------------------------------------------*/
CloseLibs()
{
   CloseLibrary( IntuitionBase );
   CloseLibrary( GfxBase );
}

/*---------------------------------------------------------------------*/
/*                     Benoetigte Libraries oeffnen                    */
/*                                                                     */
/*                                                                     */
/*---------------------------------------------------------------------*/
LONG
OpenLibs()
{
   IntuitionBase = (struct IntuitionBase*)
                   OpenLibrary("intuition.library", 0);
   if ( IntuitionBase == NULL ) exit( FALSE );
   GfxBase       = (struct GfxBase*)
                   OpenLibrary("graphics.library", 0);
   if (GfxBase == NULL) exit ( FALSE );
   return( TRUE );
}

/*---------------------------------------------------------------------*/
/*                    Haupt-Programm BITMAP-Analyser                   */
/*                                                                     */
/*                      (Device und Screen oeffnen)                    */
/*---------------------------------------------------------------------*/
main()
{
struct MsgPort *diskport;
struct IOExtTD *diskreq;
struct Screen *Screen;

   if (!OpenLibs()) exit(FALSE);

   if ((diskport = CreatePort(0L,0)) == NULL)
   {
      printf("Port nicht zu öffnen\n");
      exit(FALSE);
   }
   diskreq = (struct IOExtTD *)CreateExtIO(diskport,
                      (long)sizeof(struct IOExtTD));
   if (diskreq == 0)
   {
      printf("DiskRequest nicht zu erstellen!, Error %ld\n",diskreq);
      DeletePort(diskport);
      exit(FALSE);
   }
   if ( OpenDevice(TD_NAME, 0L, diskreq, 0L) )
   {
      printf("Device meldet Fehler!\n");
      DeletePort(diskport);
      DeleteExtIO(diskreq,(long)sizeof(struct IOExtTD));
      exit(FALSE);
   }
 
   if( (Screen = (struct Screen*)OpenScreen(&NewScreen)) == NULL )
     exit( FALSE );


   DisplayBitmap( diskreq, Screen );


   DeleteExtIO(diskreq,(long)sizeof(struct IOExtTD));
   DeletePort(diskport);

   CloseScreen( Screen );
   CloseLibs();
   exit( TRUE );
}

