home *** CD-ROM | disk | FTP | other *** search
- /* :ts=8 bk=0
- * Disk mapper. Uses trackdisk.device to grab and read sector bitmap
- * to discover what's allocated, then displays a (hopefully) pretty picture
- * showing disk useage.
- *
- * Crufted together by Leo Schwab while desperately bored. 8606.8
- * Turned into something working for the Manx compiler. 8607.23
- */
-
- #include <exec/types.h>
- #include <exec/memory.h>
- #include <intuition/intuition.h>
- #include <libraries/dos.h>
- #include <devices/trackdisk.h>
-
- #define REV 0L
- #define BLOCKSIZE TD_SECTOR
- #define NUMBLOCKS (NUMCYLS * NUMHEADS * NUMSECS)
- #define ROOTBLOCK (NUMBLOCKS / 2)
- #define BITMAPINDEX 79
- #define NUMLONGS (NUMBLOCKS / 32)
- #define XX 6L
- #define YY 6L
- #define XOFF 30L
- #define YOFF 25L
- #define BRKOVER 91L /* 11 * YY + YOFF */
- #define SEP 6
-
- extern void *OpenLibrary(), *OpenDevice(), *OpenWindow(), *AllocMem(),
- *Lock(), *Info(), *CreatePort(), *CreateExtIO();
- extern long TextLength();
-
-
- struct NewWindow windef = {
- 0, 0, 640, 180,
- -1, -1,
- CLOSEWINDOW,
- WINDOWDRAG | WINDOWDEPTH | WINDOWCLOSE | SMART_REFRESH | ACTIVATE,
- NULL, NULL,
- (UBYTE *) "Disk Allocation Map ",
- NULL, NULL, 0, 0, 0, 0,
- WBENCHSCREEN
- };
-
- struct IntuiText ok = {
- AUTOFRONTPEN, AUTOBACKPEN,
- AUTODRAWMODE, AUTOLEFTEDGE, AUTOTOPEDGE,
- AUTOITEXTFONT,
- (UBYTE *) "OK",
- AUTONEXTTEXT
- };
-
- struct IntuiText errmsg = {
- AUTOFRONTPEN, AUTOBACKPEN,
- AUTODRAWMODE, AUTOLEFTEDGE, AUTOTOPEDGE,
- AUTOITEXTFONT,
- NULL, /* Gets filled in later */
- AUTONEXTTEXT
- };
-
- struct Window *win;
- struct RastPort *rp;
- struct InfoData *id;
- struct IOExtTD *diskreq;
- struct MsgPort *diskport;
- ULONG diskchangecount, lok, *diskbuffer;
- void *IntuitionBase, *GfxBase;
-
-
- main (ac, av)
- char *av[];
- {
- long k, x, y;
- int unit, bmsect, free = NUMBLOCKS-2;
- short i, n, l;
- char buf[80];
-
- if (!ac) { /* Run from workbench (ick!) */
- /* I'll make this part better someday..... */
- strcpy (buf, "df0:");
- } else { /* Run from CLI (thank you) */
- if (ac == 1) {
- printf ("Drive specifier: ");
- gets (buf);
- } else
- strcpy (buf, av[1]);
- }
-
- openstuff ();
-
- if (!(lok = Lock (buf, ACCESS_READ)))
- die ("Can't obtain lock for specified device.");
-
- if (!(id = AllocMem ((long) sizeof (*id), MEMF_CLEAR)))
- die ("Can't get InfoData memory.");
-
- if (!Info (lok, id))
- die ("Call to Info() failed.");
-
- if (id -> id_DiskType == ID_NO_DISK_PRESENT)
- die ("No disk in drive.");
-
- unit = id -> id_UnitNumber;
- FreeMem (id, (long) sizeof (*id)); id = NULL;
- opendisk (unit);
- MotorOn ();
- GetSector ((long) ROOTBLOCK);
- bmsect = diskbuffer[BITMAPINDEX];
- GetSector ((long) bmsect);
- MotorOff ();
-
- /*
- * At this point, we now have the bitmap in the disk buffer.
- * This is what the first longword in the bitmap represents:
- *
- * 333322222222221111111111
- * 32109876543210987654321098765432 Sector #
- * --------------------------------
- * 10100101001010010010010001010011 Longword
- * MSB LSB
- *
- * If the bit is set, the sector is free.
- *
- * Sectors 0 and 1 contain the boot block. Thus, the DOS is not
- * allowed to walk on them, and they are permanently allocated.
- * However, the bitmap does not reflect this i.e. the bitmap starts
- * at sector 2, which is indicated by bit 0, longword 1. This means
- * we have to offset everything by two. Can you say "crock?"
- *
- * Actually, I suppose this is good, since it prevents some would-be
- * smart person from un-allocating those sectors and messing things
- * up badly.
- *
- * Bitmap starts at longword 1; longword 0 appears to be some kind
- * of significant garbage (checksum?)
- *
- * For more info on how I found the bitmap sector, consult the DOS
- * Technical Reference Manual, p. 1-1 - 1-2
- */
-
- SetAPen (rp, 3L);
- RectFill (rp, XOFF, YOFF, XX+XOFF, YY+YY+YOFF); /* Show first two */
- for (i=1; i<=NUMLONGS; i++) {
- k = diskbuffer[i];
- for (n=0; n<32; n++)
- /* Bits progress from low to high order */
- if (i<NUMLONGS || n<30) { /* Ignore last two */
- if (~k & 1) {
- /* Perform icky conversion */
- free--;
- l = (i-1 << 5) + n + 2;
- x = (l / 22) * XX + XOFF;
- y = (l % 22) * YY + YOFF;
- if (y >= BRKOVER)
- y += SEP;
- RectFill (rp, x, y, x+XX-1, y+YY-1);
- }
- k >>= 1;
- }
- }
-
- /* Draw grid so we can see */
- SetAPen (rp, 1L);
- for (x=XOFF; x<=80*XX+XOFF; x += XX) {
- Move (rp, x, YOFF);
- Draw (rp, x, YOFF+11*YY);
- Move (rp, x, BRKOVER+SEP);
- Draw (rp, x, BRKOVER+SEP+11*YY);
- }
- for (y=0; y<=11*YY; y += YY) {
- Move (rp, XOFF, y+YOFF);
- Draw (rp, XOFF+80*XX, y+YOFF);
- Move (rp, XOFF, y+SEP+BRKOVER);
- Draw (rp, XOFF+80*XX, y+SEP+BRKOVER);
- }
-
- /* Draw map markings */
- Move (rp, XOFF+XX/2, YOFF); Draw (rp, XOFF+XX/2, YOFF-3);
- Move (rp, XOFF+80*XX-XX/2, YOFF); Draw (rp, XOFF+80*XX-XX/2, YOFF-3);
- Move (rp, XOFF, YOFF+YY/2); Draw (rp, XOFF-3, YOFF+YY/2);
- Move (rp, XOFF, YOFF+YY*10+YY/2); Draw (rp, XOFF-3, YOFF+YY*10+YY/2);
- Move (rp, XOFF-1, YOFF-3); Text (rp, "0", 1L);
- Move (rp, XOFF+79*XX-1, YOFF-3); Text (rp, "79", 2L);
- Move (rp, XOFF-12, YOFF+6); Text (rp, "0", 1L);
- Move (rp, XOFF-20, YOFF+11*YY); Text (rp, "10", 2L);
-
- /* Do labels */
- sprintf (buf, "Bitmap on sector %d", bmsect);
- Move (rp, XOFF, 176L);
- Text (rp, buf, (long) strlen (buf));
- sprintf (buf, "Sectors free: %d", free);
- Move (rp, 250L, 176L);
- Text (rp, buf, (long) strlen (buf));
- sprintf (buf, "Allocated: %d", (int) NUMBLOCKS-free);
- Move (rp, 450L, 176L);
- Text (rp, buf, (long) strlen (buf));
- Move (rp, 520L, 60L);
- Text (rp, "Surface 0", 9L);
- Move (rp, 520L, 132L);
- Text (rp, "Surface 1", 9L);
-
- /* Wait for close gadget */
- Wait (1L << win -> UserPort -> mp_SigBit);
- closestuff ();
- }
-
-
- openstuff ()
- {
- if (!(IntuitionBase = OpenLibrary ("intuition.library", REV))) {
- /*
- * If we can't open Intuition, then we can't use
- * AutoRequest ()
- */
- printf ("Intuition failed; you'll have to use logic.\n");
- closestuff ();
- exit (100);
- }
-
- if (!(GfxBase = OpenLibrary ("graphics.library", REV))) {
- printf ("Art shop closed.\n");
- closestuff ();
- exit (100);
- }
-
- if (!(win = OpenWindow (&windef))) {
- printf ("Window painted shut.\n");
- closestuff ();
- exit (100);
- }
- rp = win -> RPort;
- }
-
- opendisk (unit)
- int unit;
- {
- long err;
- char *buf[80];
-
- if (!(diskport = CreatePort (NULL, NULL)))
- die ("No port.");
-
- if (!(diskreq = CreateExtIO (diskport, (long) sizeof (*diskreq))))
- die ("Can't make IO block.");
-
- if (err = OpenDevice (TD_NAME, (long) unit, diskreq, NULL)) {
- sprintf (buf, "Can't get at disk; err = %ld.", err);
- DeleteExtIO (diskreq, (long) sizeof (*diskreq));
- diskreq = NULL;
- die (buf);
- }
-
- if (!(diskbuffer = AllocMem (BLOCKSIZE, MEMF_CLEAR | MEMF_CHIP)))
- die ("Can't allocate disk buffer.");
-
- diskreq -> iotd_Req.io_Command = TD_CHANGENUM;
- DoIO (diskreq);
- diskchangecount = diskreq -> iotd_Req.io_Actual;
- }
-
- closestuff ()
- {
- if (lok)
- UnLock (lok);
- if (diskreq) {
- CloseDevice (diskreq);
- DeleteExtIO (diskreq, (long) sizeof (*diskreq));
- }
-
- if (diskbuffer)
- FreeMem (diskbuffer, (long) BLOCKSIZE);
- if (id)
- FreeMem (id, (long) sizeof (*id));
- if (diskport)
- DeletePort (diskport);
- if (win)
- CloseWindow (win);
- if (GfxBase)
- CloseLibrary (GfxBase);
- if (IntuitionBase)
- CloseLibrary (IntuitionBase);
- }
-
- die (str)
- UBYTE *str;
- {
- errmsg.IText = str;
- AutoRequest (win, &errmsg, NULL, &ok, NULL, NULL,
- TextLength (rp, str, (long) strlen (str)) + 40, 46L);
- closestuff ();
- exit (100);
- }
-
- /*
- * The following routines were stolen from an RKM example by Bob Peck and
- * hacked up a bit.
- */
-
- GetSector (sector)
- long sector;
- {
- LONG offset = sector * BLOCKSIZE;
-
- diskreq -> iotd_Req.io_Length = BLOCKSIZE;
- diskreq -> iotd_Req.io_Data = (APTR) diskbuffer;
- /* show where to put the data when read */
- diskreq -> iotd_Req.io_Command = ETD_READ;
- /* check that disk not changed before reading */
- diskreq -> iotd_Count = diskchangecount;
-
- /* convert from cylinder, head, sector to byte-offset value to get
- * right one (as dos and everyone else sees it)...*/
-
- /* driver reads one CYLINDER at a time (head does not move for
- * 22 sequential sector reads, or better-put, head doesnt move for
- * 2 sequential full track reads.)
- */
-
- diskreq -> iotd_Req.io_Offset = offset;
- DoIO (diskreq);
- return (0);
- }
-
- MotorOn()
- {
- /* TURN ON DISK MOTOR ... old motor state is returned in io_Actual */
- diskreq -> iotd_Req.io_Length = 1;
- /* this says motor is to be turned on */
- diskreq -> iotd_Req.io_Command = TD_MOTOR;
- /* do something with the motor */
- DoIO (diskreq);
- return (0);
- }
-
- MotorOff()
- {
- diskreq -> iotd_Req.io_Length = 0;
- /* says that motor is to be turned on */
- diskreq -> iotd_Req.io_Command = TD_MOTOR;
- /* do something with the motor */
- DoIO (diskreq);
- return (0);
- }
-