/* :ts=8 bk=0 * File mapper. Uses trackdisk.device to grab sectors and traverse the * filesystem the hard way to find out what sectors a particular file * occupies. * * Crufted together by Leo Schwab while waiting for an open line on the WELL. * 8608.19 * Finally finished: 8609.16 * I could have done it quicker if I hadn't started working for Wendy's. * * Note: This program is only valid for 3.5" floppy drives. */ #include #include #include #include #include #include "things.h" extern struct NewWindow windef; extern struct IntuiText errmsg, ok; extern struct Gadget gad[]; extern char filename[], devname[]; struct Window *win; struct RastPort *rp; struct InfoData *id; struct IOExtTD *diskreq; struct MsgPort *diskport; ULONG diskchangecount, *diskbuffer, bitmap[SIZE]; int bmsect; void *IntuitionBase, *GfxBase, *lok; main (ac, av) char *av[]; { struct IntuiMessage *msg; struct Gadget *ptr; int class; if (ac) { ac--; av++; if (ac) { strcpy (devname, *av); ac--; av++; } else strcpy (devname, "df0:"); if (ac) strcpy (filename, *av); else strcpy (filename, ":"); } openstuff (); drawgrid (); setdev (); /* Process IntuiEvents */ for ever { WaitPort (win -> UserPort); msg = GetMsg (win -> UserPort); class = msg -> Class; ptr = (struct Gadget *) msg -> IAddress; ReplyMsg (msg); if (class == CLOSEWINDOW) break; else if (class == GADGETUP) { if (ptr == gad) { /* New filename */ drawbitmap (); findfile (filename); } else if (ptr == &gad[1]) /* New device */ setdev (); else if (ptr == &gad[2]) { /* Refresh screen */ getbitmap (); drawbitmap (); findfile (filename); } } } closestuff (); } setdev () { int unit; /* * This rather lengthy series of DOS calls is needed to turn DOS * device names into unit numbers that OpenDevice() can deal with. */ if (!(lok = Lock (devname, 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; UnLock (lok); lok = NULL; opendisk (unit); getbitmap (); drawbitmap (); } getbitmap () { register int i; MotorOn (); GetSector ((long) ROOTBLOCK); bmsect = diskbuffer [BITMAPINDEX]; GetSector ((long) bmsect); MotorOff (); for (i=0; i= BRKOVER) y += SEP; /* * The following incantation basically means, * don't draw sectors that don't need to be * drawn. */ p = ReadPixel (rp, x+1, y+1); if (~k & 1) { free--; if (p != 3) { SetAPen (rp, 3L); RectFill (rp, x+1, y+1, x+XX-1, y+YY-1); } } else if (p) { SetAPen (rp, 0L); RectFill (rp, x+1, y+1, x+XX-1, y+YY-1); } k >>= 1; } l++; /* Increment sector number */ } } /* Do labels */ SetAPen (rp, 1L); SetBPen (rp, 0L); SetDrMd (rp, JAM2); sprintf (buf, "Bitmap on sector %-4d", bmsect); Move (rp, XOFF, LABEL_Y); Text (rp, buf, (long) strlen (buf)); sprintf (buf, "Sectors free: %-4d", free); Move (rp, 250L, LABEL_Y); Text (rp, buf, (long) strlen (buf)); sprintf (buf, "Allocated: %-4d", (int) NUMBLOCKS-free); Move (rp, 450L, LABEL_Y); Text (rp, buf, (long) strlen (buf)); Move (rp, NUMCYLS*XX+XOFF+10, NUMSECS*YY/2+YOFF+2); Text (rp, "Surface 0", 9L); Move (rp, NUMCYLS*XX+XOFF+10, NUMSECS*YY/2+BRKOVER+SEP+2); Text (rp, "Surface 1", 9L); } drawgrid () /* Draw grid and labels so we can see */ { long x, y; SetDrMd (rp, JAM1); 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-4); Text (rp, "0", 1L); Move (rp, XOFF+79*XX-1, YOFF-4); 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); } marksector (n, color) long n; int color; { register int x, y; x = (n / 22) * XX + XOFF; y = (n % 22) * YY + YOFF; if (y >= BRKOVER) y += SEP; SetAPen (rp, (long) color); RectFill (rp, x+1L, y+1L, x+XX-1L, y+YY-1L); } 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; if (!(diskport = CreatePort (NULL, NULL))) die ("No port."); if (!(diskreq = CreateExtIO (diskport, (long) sizeof (*diskreq)))) die ("Can't make IO block."); if (!(diskbuffer = AllocMem (BLOCKSIZE, MEMF_CLEAR | MEMF_CHIP))) die ("Can't allocate disk buffer."); } opendisk (unit) int unit; { long err; char *buf[80]; /* We may be changing units, so close it if it's open */ if (diskreq -> iotd_Req.io_Device) { CloseDevice (diskreq); diskreq -> iotd_Req.io_Device = NULL; } if (err = OpenDevice (TD_NAME, (long) unit, diskreq, NULL)) { sprintf (buf, "Can't get at disk; err = %ld.", err); die (buf); } diskreq -> iotd_Req.io_Command = TD_CHANGENUM; DoIO (diskreq); diskchangecount = diskreq -> iotd_Req.io_Actual; } closestuff () { if (lok) UnLock (lok); if (diskreq) { /* * Apparently, if OpenDevice() fails, it fills in the * io_Device field with -1. This pretty much blows all * my previous code out of the water, which assumed it got * filled in with 0. Sigh. Why don't they tell us these * things? */ if ((long) diskreq -> iotd_Req.io_Device != -1L) 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); } notice (str) /* For non-fatal errors */ UBYTE *str; { MotorOff (); errmsg.IText = str; AutoRequest (win, &errmsg, NULL, &ok, NULL, NULL, TextLength (rp, str, (long) strlen (str)) + 40, 46L); } die (str) /* For fatal errors */ UBYTE *str; { errmsg.IText = str; AutoRequest (win, &errmsg, NULL, &ok, NULL, NULL, TextLength (rp, str, (long) strlen (str)) + 40, 46L); closestuff (); exit (100); } /* Guess.... debug (str) char *str; { printf (str); getchar (); } */