/****************************************************************************/
/*                                                                          */
/* Module:     bootsec.c                                                    */
/*                                                                          */
/* Function:   Display floppy boot sector data                              */
/*                                                                          */
/* Programmer: George R. Woodside                                           */
/*                                                                          */
/* Date:       November 10, 1987                                            */
/*                                                                          */
/****************************************************************************/

/****************************************************************************/
/* INCLUDE FILES                                                            */
/****************************************************************************/

#include <stdio.h>
#include <ctype.h>
#include <errno.h>
#include <osbind.h>

#define  BSWAP(low,high)  ((high << 8) + (low & 0xff))

unsigned  char  buf[512];               /* boot sector buffer               */

main(argc,argv)
int    argc;                            /* argument count                   */
char  *argv[];                          /* argument pointers                */
{

  register  int  arg;                   /* current argument                 */

  if(argc < 2)                          /* if no arguments                  */
    {
      printf("Usage: bootsec drive {drive}\n"); /* simple usage             */
      exit(0);                          /* exit without error               */
    }                                   /* end no arguments                 */

  for(arg = 1; arg < argc; arg++)       /* for each request                 */
    show_boot(argv[arg]);               /* display it                       */

  deskey();                             /* hold screen if from desktop      */
  return(0);                            /* and exit without error           */
}                                       /* end main                         */

/****************************************************************************/
/* Read and display boot sector data                                        */
/****************************************************************************/
show_boot(drive)
char  *drive;                           /* drive to process                 */
{
  register  int   i;                    /* generic counter                  */
  register  int   dno;                  /* binary drive number              */
  register  int   value;                /* de-swapped value                 */
  register  long  reply;                /* I/O reply                        */
  register  long  did;                  /* disk ID value                    */

  if(*drive == '-')                     /* if leading dash                  */
    drive++;                            /* skip to drive id                 */

  if(isupper(*drive))                   /* if upper case                    */
    dno = *drive - 'A';                 /* convert to binary                */
  else if(islower(*drive))              /* try lower case                   */
    dno = *drive - 'a';                 /* convert to binary                */
  else                                  /* illegal request                  */
    {
      printf("bootsec: Illegal drive request %c\n",*drive); /* report error */
      exit(1);                          /* punt                             */
    }                                   /* end bad drive                    */

  reply = Rwabs(0,buf,1,0,dno);         /* try the read                     */

  if(reply == AE_CHNG)                  /* if media change error            */
    {
      reply = Getbpb(dno);              /* clear media change               */
      reply = Rwabs(0,buf,1,0,dno);     /* retry the read                   */
    }                                   /* end media change error           */

  if(reply)                             /* if a read error                  */
    {
      printf("bootsec: Read error %ld\n",reply); /* display error code      */
      exit(1);                          /* punt                             */
    }                                   /* end bad read                     */

  printf("Drive:                 %c\n",dno + 'A'); /* note drive            */
  printf("Jump instruction:     %02x %02x %02x\n",buf[0],buf[1],buf[2]);
  printf("ID:                   ");     /* note ID is next                  */

  for(i = 3; i < 11; i++)               /* ID is eight bytes                */
    printf("%02x ",buf[i]);             /* print one byte in hex            */

  printf("\n                       ");  /* re-align                         */

  for(i = 3; i < 11; i++)               /* set up again                     */
    {
      if(isprint(buf[i]))               /* if printable                     */
        printf("%c  ",buf[i]);          /* print one byte in ASCII          */
      else                              /* unprintable                      */
        printf("   ");                  /* stay aligned                     */
    }                                   /* end ASCII ID                     */

  did = buf[8] & 0xff;                  /* get first serial number          */
  did = (did << 8) | (buf[9] & 0xff);   /* second byte                      */
  did = (did << 8) | (buf[10] & 0xff);  /* third byte                       */

  printf(" (Serial Number: %8ld)\n",did); /* finished with ID               */

  value = BSWAP(buf[11],buf[12]);       /* extract bytes per sector         */
  printf("Bytes per sector:   %4d\t\t",value); /* print it                  */
  printf("Sectors per cluster:  %2d\n",buf[13]); /* sectors per cluster     */
  value = BSWAP(buf[14],buf[15]);       /* extract reserved sectors         */
  printf("Reserved sectors:   %4d\t\t",value); /* print it                  */
  printf("Copies of FAT:        %2d\n",buf[16]); /* number of FAT copies    */
  value = BSWAP(buf[17],buf[18]);       /* extract directory entries        */
  printf("Directory entries:  %4d\t\t",value); /* print it                  */
  value = BSWAP(buf[19],buf[20]);       /* extract sectors on disk          */
  printf("Sectors on disk:   %5d\n",value); /* print it                     */
  printf("Format ID:            %02x\t\t",buf[21] & 0xff); /* format type   */
  value = BSWAP(buf[22],buf[23]);       /* extract sectors per FAT          */
  printf("Sectors per FAT:    %4d\n",value); /* print it                    */
  value = BSWAP(buf[24],buf[25]);       /* extract sectors per track        */
  printf("Sectors per track:  %4d\t\t",value); /* print it                  */
  value = BSWAP(buf[26],buf[27]);       /* extract heads/sides              */
  printf("Sides on disk:      %4d\n",value); /* print it                    */
  value = BSWAP(buf[28],buf[29]);       /* extract reserved sectors         */
  printf("Special reserved:   %4d\n",value); /* print it                    */
}                                       /* end display data                 */
