/*-----------------------------------------------------*/
/*                 Bitmap - Analyzer                   */
/*                                                     */
/*                   JEA, 08-15-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,
   200,
   2,
   0, 1,
   HIRES|SPRITES,
   CUSTOMSCREEN,
   &MyFont,
   "- BitMap -",
   NULL,
   NULL,
};
/*-----------------------------------------------------*/
/*                Switch Motor on and off              */
/*                                                     */
/*                                                     */
/*-----------------------------------------------------*/
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);
}
/*-----------------------------------------------------*/
/*             Read Block from Device indicated        */
/*                                                     */
/*                                                     */
/*-----------------------------------------------------*/
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);
}
/*-----------------------------------------------------*/
/*              Search for Bitmap-Block and read       */
/*                                                     */
/*                                                     */
/*-----------------------------------------------------*/
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] );
}
/*-----------------------------------------------------*/
/*         Display Bitmap of the Device indicated      */
/*                                                     */
/*                                                     */
/*-----------------------------------------------------*/
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, "Side   0", 7 );
   Move( Window->RPort, 500, 105 );
   Text( Window->RPort, "Side   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, "Sector 1.", 9 );
   Move( Window->RPort, 480, 64 );
   Text( Window->RPort, "Sector 11.", 10 );
   Move( Window->RPort, 480, 80 );
   Text( Window->RPort, "Sector 1.", 9 );
   Move( Window->RPort, 480, 136 );
   Text( Window->RPort, "Sector 11.", 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 );
}
/*-----------------------------------------------------*/
/*                 Close Libraries                     */
/*                                                     */
/*                                                     */
/*-----------------------------------------------------*/
CloseLibs()
{
   CloseLibrary( IntuitionBase );
   CloseLibrary( GfxBase );
}
/*-----------------------------------------------------*/
/*                    Open Libraries                   */
/*                                                     */
/*                                                     */
/*-----------------------------------------------------*/
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 );
}
/*-----------------------------------------------------*/
/*              Main-Program BITMAP-Analyzer           */
/*                                                     */
/*                (open Device and Screen)             */
/*-----------------------------------------------------*/
main()
{
struct MsgPort *diskport;
struct IOExtTD *diskreq;
struct Screen *Screen;
   if (!OpenLibs()) exit(FALSE);
   if ((diskport = CreatePort(0L,0)) == NULL)
   {
      printf("Port can't be opened\n");
      exit(FALSE);
   }
   diskreq = (struct IOExtTD *)CreateExtIO(diskport,
                      (long)sizeof(struct IOExtTD));
   if (diskreq == 0)
   {
      printf("DiskRequest can't be created !, Error %ld\n",diskreq);

      DeletePort(diskport);
      exit(FALSE);
   }
   if ( OpenDevice(TD_NAME, 0L, diskreq, 0L) )
   {
      printf("Device reports error!\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 );
}


















