/******************************************
 *                                        *
 * Programm: Disketten-BitMap analysieren *
 * ====================================== *
 *                                        *
 * Autor:  Datum:      Kommentar:         *
 * ------  ----------  ----------         *
 * Wgb     24.07.1988  Ausgabe auf        *
 *                     Workbench-Window   *
 *                                        *
 *****************************************/


#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


struct IntuitionBase *IntuitionBase;
struct GfxBase       *GfxBase;

struct Window    *OpenWindow();
struct Window    *Window;
struct NewWindow NewWindow =
   {
   0, 0,
   640, 180,
   0, 1,
   CLOSEWINDOW |
   DISKINSERTED |
   DISKREMOVED,
   WINDOWCLOSE   | SMART_REFRESH | ACTIVATE    |
   WINDOWDRAG    | WINDOWDEPTH   |WINDOWSIZING |
   NOCAREREFRESH | GIMMEZEROZERO,
   NULL,
   NULL,
   (UBYTE *)" BITMAP ",
   NULL,
   NULL,
   550, 158,
   640, 256,
   WBENCHSCREEN
   };

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

struct MsgPort *diskport;
struct IOExtTD *diskreq;

LONG *AllocMem();
void *OpenLibrary();


/***************************************
 *                                     *
 * Funktion: Motor ein- / ausschalten  *
 * =================================== *
 *                                     *
 * Autor:  Datum:      Kommentar:      *
 * ------  ----------  ----------      *
 * Wgb     24.07.1988                  *
 *                                     *
 *                                     *
 ***************************************/

void Motor(DiskReq, Switch)
struct IOExtTD *DiskReq;
LONG            Switch;
   {
   DiskReq->iotd_Req.io_Length  = Switch;
   DiskReq->iotd_Req.io_Command = TD_MOTOR;

   DoIO(DiskReq);
   }


/***************************************
 *                                     *
 * Funktion: Daten-Block lesen         *
 * =================================== *
 *                                     *
 * Autor:  Datum:      Kommentar:      *
 * ------  ----------  ----------      *
 * Wgb     24.07.1988                  *
 *                                     *
 *                                     *
 ***************************************/

void 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;

   DoIO(DiskReq);
   }


/***************************************
 *                                     *
 * Funktion: Daten-Block einlesen      *
 * =================================== *
 *                                     *
 * Autor:  Datum:      Kommentar:      *
 * ------  ----------  ----------      *
 * Wgb     24.07.1988                  *
 *                                     *
 *                                     *
 ***************************************/

LONG
ReadBitmap(DiskReq, Puffer)
struct IOExtTD *DiskReq;
LONG           *Puffer;
   {
   ULONG DiskChangeCount;

   DiskReq->iotd_Req.io_Command = TD_CHANGENUM;

   DoIO(DiskReq);

   DiskChangeCount = DiskReq->iotd_Req.io_Actual;

   Motor(DiskReq, ON);

   ReadBlock(diskreq, 880L, Puffer, DiskChangeCount);

   if(Puffer[BM_FLAG])
      ReadBlock(DiskReq, Puffer[BM_BLOCKS], Puffer);

   Motor(DiskReq, OFF);

   return(Puffer[BM_FLAG]);
   }


/***************************************
 *                                     *
 * Funktion: BitMap grafisch ausgeben  *
 * =================================== *
 *                                     *
 * Autor:  Datum:      Kommentar:      *
 * ------  ----------  ----------      *
 * Wgb     24.07.1988                  *
 *                                     *
 *                                     *
 ***************************************/

ULONG Koords[][2] =
   {
   510L,  38L,
   510L, 110L,
    10L, 149L,
   223L, 149L,
   476L, 149L,
   495L,  13L,
   495L,  69L,
   495L,  85L,
   495L, 141L
   };

char *Texte[] =
   {
   "Surface 0",
   "Surface 1",
   "0",
   "Track",
   "79",
   "1. Sektor",
   "11. Sektor",
   "1. Sektor",
   "11. Sektor"
   };

DisplayBitmap(DiskReq)
struct IOExtTD *DiskReq;
   {
   LONG *buf;
   LONG x, xoff = 10;
   LONG y, yoff = 5;
   ULONG loop;

   int i;

   ULONG  MessageClass;
   USHORT code;

   struct Message      *GetMsg();
   struct IntuiMessage *message;
   struct RastPort     *Port;

   Port = Window->RPort;

   SetDrMd(Port, 0L);

	for(i=0; i<9; i++)
      {
      SetAPen(Port, 2L);
      Move(Port, Koords[i][0]+1L, Koords[i][1]+1L);
      Text(Port, Texte[i], (LONG)strlen(Texte[i]));
      SetAPen(Port, 1L);
      Move(Port, Koords[i][0], Koords[i][1]);
      Text(Port, Texte[i], (LONG)strlen(Texte[i]));
      }

   SetDrMd(Port, 1L);

   buf = 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 (Port, 1L);
         else
            SetAPen (Port, 3L);

         if (y > 10)
            RectFill(Port, xoff+x*6, yoff+(y+1)*6,
                     xoff+x*6+4, yoff+(y+1)*6+4-1);
         else
            RectFill(Port, xoff+x*6, yoff+y*6,
                     xoff+x*6+4, yoff+y*6+4-1);

         ++loop;
         }
      }

   FreeMem(buf, 512L);


   FOREVER
      {
      if ((message = (struct IntuiMessage *)
            GetMsg(Window->UserPort)) == NULL)
         {
         Wait(1L<<Window->UserPort->mp_SigBit);
         continue;
         }

      MessageClass = message->Class;
      code         = message->Code;

      ReplyMsg(message);

      Move(Port, 264L, 160L);

      switch (MessageClass)
         {
         case CLOSEWINDOW : Close_All(TRUE);
                            break;

         case DISKREMOVED : Text(Port, "DISK  REMOVED", 13L);
                            Delay(50L);
                            break;

         case DISKINSERTED: Text(Port, "DISK INSERTED", 13L);
                            Delay(50L);
                            break;
         }

      Move(Port, 264L, 160L);
      Text(Port, "             ", 13L);
      }
   }


/***************************************
 *                                     *
 * Funktion: Alles geöffnete schließen *
 * =================================== *
 *                                     *
 * Autor:  Datum:      Kommentar:      *
 * ------  ----------  ----------      *
 * Wgb     24.07.1988  Intuition, Gfx  *
 *                                     *
 *                                     *
 ***************************************/

Close_All(Ende)
BOOL Ende;
   {
   if (diskport)      DeletePort(diskport);
   if (diskreq)       DeleteExtIO(diskreq, (LONG)sizeof(struct IOExtTD));
   if (Window)        CloseWindow(Window);
   if (IntuitionBase) CloseLibrary(IntuitionBase);
   if (GfxBase)       CloseLibrary(GfxBase);

   exit(Ende);
   }


/***************************************
 *                                     *
 * Funktion: Libraries öffnen          *
 * =================================== *
 *                                     *
 * Autor:  Datum:      Kommentar:      *
 * ------  ----------  ----------      *
 * Wgb     24.07.1988                  *
 *                                     *
 *                                     *
 ***************************************/

void Open_All()
   {
   if (!(IntuitionBase = (struct IntuitionBase*)
       OpenLibrary("intuition.library", 0L)))
      {
      printf("Keine Intuition.Library!\n");
      Close_All(FALSE);
      }

   if(!(Window = OpenWindow(&NewWindow)))
      {
      printf("Das Fenster will nicht aufgehen!\n");
      Close_All(FALSE);
      }

   if (!(GfxBase = (struct GfxBase*)
       OpenLibrary("graphics.library", 0L)))
      {
      printf("Keine Graphics.Library!\n");
      Close_All(FALSE);
      }

   if (!(diskport = CreatePort(0L, 0)))
      {
      printf("Port nicht zu öffnen\n");
      Close_All(FALSE);
      }

   diskreq = (struct IOExtTD *)CreateExtIO(diskport,
                      (LONG)sizeof(struct IOExtTD));
   if (diskreq == 0)
      {
      printf("DiskRequest nicht zu erstellen!, Error %ld\n",diskreq);
      Close_All(FALSE);
      }

   if (OpenDevice(TD_NAME, 0L, diskreq, 0L))
      {
      printf("Device meldet Fehler!\n");
      Close_All(FALSE);
      }

   }


/***************************************
 *                                     *
 * Funktion: Hauptprogramm             *
 * =================================== *
 *                                     *
 * Autor:  Datum:      Kommentar:      *
 * ------  ----------  ----------      *
 * Wgb     24.07.1988  nur Unterprg.   *
 *                     aufrufen        *
 *                                     *
 ***************************************/

main()
   {
   Open_All();

   DisplayBitmap(diskreq);
   }

