/* DSKINFO
 *
 *
 */
#include <functions.h>		/* to hell with Lattice */
#include <exec/types.h>
#include <exec/nodes.h>
#include <exec/lists.h>
#include <exec/memory.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>
#include <libraries/filehandler.h>

#include <exec/interrupts.h>
#include <exec/ports.h>
#include <exec/libraries.h>
#include <exec/io.h>
#include <exec/tasks.h>
#include <exec/execbase.h>
#include <exec/devices.h>
#include <devices/trackdisk.h>

#define	TD_READ	CMD_READ

extern struct DosLibrary *DOSBase;	/* DOS Library base pointer */

SHORT error;
struct MsgPort *read_port;
struct IOExtTD *read_req;

char *device_name;

ULONG	unit;		/* unit number					*/
ULONG	flags;		/* file system flags				*/
ULONG	capacity;	/* total sectors per unit (calculated)		*/
ULONG	bcapacity;	/* unit's capacity in bytes (calculated)	*/
ULONG	tblsize;	/* table size: standard value is 11		*/
ULONG	sizblk;		/* blocksize in longwords; standard is 128	*/
ULONG	secorg;		/* secorg: not used, must be 0			*/
ULONG	numheads;	/* number of heads/cylinder, drive specific	*/
ULONG	secblk;		/* number of sectors/block, not used, must be 1	*/
ULONG	blkstrk;	/* blocks per track, drive specific		*/
ULONG	reserved;	/* sectors reserved at start, usually 2		*/
ULONG	prefac;		/* prefac, not used, must be 0			*/
ULONG	interleave;	/* interleave, usually 0			*/
ULONG	locyl;		/* low cylinder number, typically 0		*/
ULONG	hicyl;		/* high cylinder number, drive specific		*/
ULONG	numbufs;	/* starting number of buffers, typically 5	*/
ULONG	membuftype;	/* memory buffer type, default is 3, and	*/
			/*    hard disks want 0				*/

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

main(argc, argv)
   int argc;
   char *argv[];
{
   char buf[128];
	
   read_port = CreatePort(0, 0);
   if (read_port == NULL)
      quit(100);

   read_req =(struct IOExtTD *)CreateExtIO(read_port,sizeof(struct IOExtTD));
   if (read_req == NULL)
      quit(200);

   strcpy(buf, "df1");
   if (argc > 1)
      strcpy(buf, argv[1]);
   if (buf[3] == ':')
      buf[3] = 0;
   if (buf[4] == ':')
      buf[4] = 0;

   init_device (buf);

   error = OpenDevice (device_name, unit, read_req, 0);
   if (error) {
      printf("OpenDevice return was: %lx\n", error);
      quit(1);
   }

printf("/* Table size = %ld, sectors/block = %ld\n", tblsize, secblk);
printf(" * Size of a block = %ld longwords, %ld bytes\n", sizblk, sizblk*4L);
printf(" * Formatted capacity = %ld blocks, %ld bytes, %ldK, %ld.%1ldM\n",
                   capacity,
                   bcapacity,
                   bcapacity / 1024L,
                   bcapacity / 1048576L,
                   (bcapacity % 1048576L) / 104857L);
printf(" */\n%s:       Device = %s\n", buf, device_name);
printf("           Unit = %ld\n", unit);
printf("           Flags = %ld\n", flags);
printf("           Surfaces = %ld\n", numheads);
printf("           BlocksPerTrack = %ld\n", blkstrk);
printf("           Reserved = %ld\n", reserved);
printf("           Interleave = %ld\n", interleave);
printf("           LowCyl = %ld ; HighCyl = %ld\n", locyl, hicyl);
printf("           Buffers = %ld\n", numbufs);
if (12 == tblsize)
printf("           BufMemType = %ld /* 3 = chip, 0 = fast */\n", membuftype);
else
printf("           BufMemType = 0 /* table short; 3 = chip, 0 = fast */\n");
printf("#\n");

   MotorOff();
   CloseDevice(read_req);
   quit(0);
}


MotorOff()
{
   read_req->iotd_Req.io_Length = 0;
   read_req->iotd_Req.io_Command = TD_MOTOR;
   DoIO(read_req);
   return(0);
}

quit(return_code)
{
   if (read_req)
      DeleteExtIO(read_req);
   if (read_port)
      DeletePort(read_port);
   printf("\233 p");		/* turn cursor back on */
   exit(return_code);
}


init_device (name)
   register char *name;
{
   struct          RootNode          *root_node;
   struct          DosInfo           *info_node;
   register struct DeviceNode        *device_node;
   struct          FileSysStartupMsg *startup_msg;
   ULONG                             *envptr;


   root_node = (struct RootNode *) DOSBase->dl_Root;
   info_node = (struct DosInfo *) BADDR (root_node->rn_Info);
   device_node = (struct DeviceNode *) BADDR (info_node->di_DevInfo);
   while (device_node) {
      if (device_node->dn_Type == DLT_DEVICE ) {
         if (match (name, BADDR (device_node->dn_Name) + 1) == 0)
				break;
      }
      device_node = (struct DeviceNode *) BADDR (device_node->dn_Next);
   }
   if (device_node == 0) {
      printf ("Device %s: not found\n", name);
      quit (1);
   }
   startup_msg = (struct FileSysStartupMsg *) 
                                  BADDR (device_node->dn_Startup);
   unit        =                  startup_msg->fssm_Unit; /* unit number */
   flags       =                  startup_msg->fssm_Flags;
   device_name = (char *) BADDR  (startup_msg->fssm_Device) + 1;
   envptr      = (ULONG *) BADDR (startup_msg->fssm_Environ);
   tblsize     = envptr[DE_TABLESIZE];
   sizblk      = envptr[DE_SIZEBLOCK];
   secorg      = envptr[DE_SECORG];
   numheads    = envptr[DE_NUMHEADS];
   secblk      = envptr[DE_SECSPERBLK];
   blkstrk     = envptr[DE_BLKSPERTRACK];   /* numsects */
   reserved    = envptr[DE_RESERVEDBLKS];
   prefac      = envptr[DE_PREFAC];
   interleave  = envptr[DE_INTERLEAVE];
   locyl       = envptr[DE_LOWCYL];
   hicyl       = envptr[DE_UPPERCYL];
   numbufs     = envptr[DE_NUMBUFFERS];
   membuftype  = envptr[DE_MEMBUFTYPE];

   capacity    = (hicyl - locyl + 1L) * blkstrk * numheads;
   bcapacity   = capacity * sizblk * 4L;
}

match (s1, s2)
   register char *s1, *s2;
{
   register char c;
   while ((c = toupper (*s1++)) == toupper (*s2++))
      if (c == 0)
         return (0);
   return (1);
}
