Logo Search packages:      
Sourcecode: linux86 version File versions  Download package

makeboot.c

#include <stdio.h>
#include <ctype.h>
#include <time.h>
#include <string.h>

#include "sysboot.v"
#include "noboot.v"
#include "msdos.v"
#include "msdos16.v"
#include "skip.v"
#include "killhd.v"
#include "tarboot.v"
#include "minix.v"
#include "minixhd.v"
#include "mbr.v"

unsigned char buffer[1024];

#define FS_NONE   0     /* Bootsector is complete */
#define FS_DOS    1     /* Bootsector needs 'normal' DOS FS */
#define FS_ADOS   2     /* Bootsector likes any DOS FS */
#define FS_TAR    3     /* Bootsector needs GNU-tar volume label */
#define FS_STAT   4     /* Any bootsector is checked */
#define FS_ZERO 5 /* Boot sector must be already Zapped */
#define FS_MBR  6 /* Boot sector is an MBR */

#ifndef __MSDOS__
#define X_HAS_2M20
#endif

struct bblist {
   char * name;
   char * desc;
   char * data;
   int        size;
   int  name_type;
   int      boot_name;
   int      fstype;
   int  fsmod;
} bblocks[] = {
{ "tar",  "Bootable GNU tar volume lable",
         tarboot_data, tarboot_size, 0, 0,            FS_TAR},
{ "dos12","Boot file BOOTFILE.SYS from dos floppy",
           msdos_data, msdos_size,
         1, msdos_boot_name-msdos_start,        FS_DOS, 12},
{ "dos16","Boot file BOOTFILE.SYS from FAT16 hard disk or floppy",
           msdos16_data, msdos16_size,
         1, msdos16_boot_name-msdos16_start,          FS_DOS, 16},
{ "none", "No OS bootblock, just display message",  
           noboot_data, noboot_size, 
         2, noboot_boot_message-noboot_start,   FS_ADOS},
{ "skip", "Bypasses floppy boot with message",  
           skip_data, skip_size,  
         2, skip_mesg-skip_start,               FS_ADOS},
{ "minix","Minix floppy FS booter",           
           minix_data, minix_size, 
         2, minix_bootfile-minix_start,         FS_ZERO},
{ "hdmin","Minix Hard disk FS booter",    
           minixhd_data, minixhd_size, 
         2, minixhd_bootfile-minixhd_start,           FS_ZERO},
{ "killhd", "Deletes MBR from hard disk when booted",  
           killhd_data, killhd_size,  
         2, killhd_boot_message-killhd_start,   FS_ADOS},
#if __STDC__
{ "mbr",  "Master boot record for HD"
#if defined(mbr_Banner) || mbr_diskman || mbr_linear || mbr_mbrkey || mbr_preboot
   ", Options:"
#ifdef mbr_Banner
   " Banner"
#endif
#if mbr_diskman
   " DiskMan"
#endif
#if mbr_linear
   " LBA"
#if !mbr_useCHS
   "-Only"
#endif
#endif
#if mbr_mbrkey
   " BootKeys"
#endif
#if mbr_preboot
   " PreBoot"
#endif
#endif
         ,             
           mbr_data,mbr_size, 
#ifdef mbr_Banner
         2, mbr_Banner-mbr_start,               FS_MBR},
#else
           0, 0,                          FS_MBR},
#endif
#else
{ "mbr",  "Master boot record for HD",
         mbr_data,mbr_size, 0, 0,                     FS_MBR},
#endif
{ "stat", "Display dosfs superblock",                          
           0, 0, 0, 0,                          FS_STAT},
{ "copy", "Copy boot block to makeboot.sav or named file",                   
           0, 0, 0, 0,                          FS_STAT},
{ "Zap",  "Clear boot block to NULs",                       
           0, 1024, 0, 0,                       FS_NONE},
   0
};

char * progname = "";

int disktype = 0;
FILE * diskfd;

int disk_sect = 63;     /* These are initilised to the maximums */
int disk_head = 256;    /* Set to the correct values when an MSDOS disk is */
int disk_trck = 256;    /* successfully identified */

int force = 0;
int write_zero = 1;     /* Write sector 0 */
int write_one = 0;      /* Write sector 1 */
int bs_offset = 0;      /* Offset of _real_ bootsector for 2m floppies */

char * boot_id = 0;

main(argc, argv)
int argc;
char ** argv;
{
   FILE * fd;
   struct bblist *ptr;
   int i;

   progname = argv[0];

   if( argc == 4 && strcmp(argv[1], "-f") == 0 )
   {
      argv++; argc--; force++;
   }
   if( argc != 3 ) Usage();

   boot_id = strchr(argv[1], '=');
   if( boot_id )
      *boot_id++ = '\0';

   if( (i=strlen(argv[1])) < 2 ) Usage();
   for(ptr = bblocks; ptr->name; ptr++)
      if( strncmp(argv[1], ptr->name, i) == 0 ) break;
   if( ptr->name == 0 ) Usage();

   open_disk(argv[2]);
   if( read_sector(0, buffer) != 0 )
      exit(1);
   read_sector(1, buffer+512);

   write_zero = (ptr->size >= 512);
   write_one =  (ptr->size >= 1024);

   switch(ptr->fstype)
   {
   case FS_NONE:  /* override */
   case FS_STAT:
   case FS_ADOS:
      break;
   case FS_DOS:
      check_msdos();
      if(ptr->fsmod) check_simpledos(ptr->fsmod);
      break;
   case FS_TAR:
      check_tar();
      break;
   case FS_ZERO:
      check_zapped();
      break;
   case FS_MBR:
      check_mbr();
      break;

   default:
      fprintf(stderr, "Program error, unknown filesystem requirement\n");
      exit(2);
   }

   switch(ptr->fstype)
   {
   case FS_STAT:
      if( strcmp(ptr->name, "copy") == 0 )
         save_super(buffer);
      else
         print_super(buffer);
      close_disk();
      exit(0);
   case FS_DOS:
   case FS_ADOS:
      for(i=0; i<sysboot_dosfs_stat; i++)
         buffer[i] = ptr->data[i];
      for(i=sysboot_codestart; i<512; i++)
         buffer[i] = ptr->data[i];
      break;

   case FS_TAR:
      copy_tarblock();
      break;

   case FS_MBR:
      copy_mbr(ptr->data);
      break;

   case FS_ZERO:
   case FS_NONE:
      if( ptr->data )
       memcpy(buffer, ptr->data, ptr->size);
      else
      {
       memset(buffer, '\0', 1024);
       write_one = 1;
      }
      break;
   }

   if( boot_id ) switch(ptr->name_type)
   {
   case 1:
      set_dosname(ptr->boot_name);
      break;
   case 2:
      set_asciz(ptr->boot_name);
      break;
   default:
      fprintf(stderr, "Cannot specify boot name for this block\n");
      exit(1);
   }

   if( bs_offset )
   {
      if( write_zero ) do_2m_write();
      /* Don't write 1 ever! */
   }
   else
   {
      if( write_zero ) write_sector(0, buffer);
      if( write_one )  write_sector(1, buffer+512);
   }
   close_disk();
   exit(0);
}

Usage()
{
   struct bblist *ptr = bblocks;

   if( progname == 0 || *progname == 0 || progname[1] == 0 )
      progname = "makeboot";

#ifdef __MSDOS__
   fprintf(stderr, "Usage: %s [-f] bootblock[=bootname] a:\n\n", progname);
   fprintf(stderr, "The 'a:' can be any drive or file or @: for the MBR.\n");
#else
   fprintf(stderr, "Usage: %s [-f] bootblock[=bootname] /dev/fd0\n\n", progname);
#endif
   fprintf(stderr, "The bootname is a filename or message to use with the block,\n");
   fprintf(stderr, "the blocks are:\n");
   for(;ptr->name; ptr++)
       fprintf(stderr, "\t%s\t%s\n", ptr->name, ptr->desc);
   exit(1);
}

/**************************************************************************/

int
open_disk(diskname)
char * diskname;
{
#ifdef __MSDOS__
   /* Freedos fix */
   if( diskname[2] == '\r' ) diskname[2] = 0;

   if( diskname[2] == 0 && diskname[1] == ':' )
   {
      if (isalpha(diskname[0])) {
       disktype = toupper(diskname[0])-'A'+1;
       return 0;
      }
      if (diskname[0] =='@') {
       disktype = 129;
       return 0;
      }
   }
#endif
   disktype = 0;
   diskfd = fopen(diskname, "r+b");
   if( diskfd == 0 ) diskfd = fopen(diskname, "rb");
   if( diskfd == 0 && force ) diskfd = fopen(diskname, "w+b");
   if( diskfd == 0 )
   {
      fprintf(stderr, "Cannot open '%s'\n", diskname);
      exit(1);
   }
   return 0;
}

close_disk()
{
   if( diskfd && disktype == 0 ) fclose(diskfd);
   diskfd = 0;
   disktype = 0;
}

int
write_sector(sectno, loadaddr)
int sectno;
char * loadaddr;
{
#ifdef __MSDOS__
   if( disktype == 1 || disktype == 2 || disktype == 129 )
   {
      int tries, rv;
      int s,h,c;
      s = sectno%disk_sect + 1;
      h = sectno/disk_sect%disk_head;
      c = sectno/disk_sect/disk_head;

      for(tries=0; tries<6; tries++)
         if( (rv = bios_sect_write(disktype-1, c, h, s, loadaddr)) == 0 )
            break;
      if( rv )
      {
       if (rv/256 == 3)
          fprintf(stderr, "Write protect error writing sector %d\n", sectno);
       else
          fprintf(stderr, "Error writing sector %d, (%d)\n", sectno, rv/256);
       return -1;
      }
      return 0;
   }
   if( disktype )
   {
      int tries, rv;

      for(tries=0; tries<6; tries++)
         if( (rv = dos_sect_write(disktype-1, sectno, loadaddr)) == 0 )
            break;
      if( rv )
      {
         fprintf(stderr, "Error writing sector %d, (0x%04d)\n", sectno, rv);
         memset(loadaddr, '\0', 512);
       return -1;
      }
      return 0;
   }
#endif
   if( disktype )
   {
      fprintf(stderr, "Cannot write sector %d\n", sectno);
      return -1;
   }
   fseek(diskfd, (long)sectno*512, 0);
   if( fwrite(loadaddr, 512, 1, diskfd) != 1 )
   {
      fprintf(stderr, "Cannot write sector %d\n", sectno);
      return -1;
   }
   printf("Wrote sector %d\n", sectno);
   return 0;
}

int
read_sector(sectno, loadaddr)
int sectno;
char * loadaddr;
{
   int cc;
#ifdef __MSDOS__
   if( disktype == 1 || disktype == 2 || disktype == 129 )
   {
      int tries, rv;
      int s,h,c;
      s = sectno%disk_sect + 1;
      h = sectno/disk_sect%disk_head;
      c = sectno/disk_sect/disk_head;

      for(tries=0; tries<6; tries++)
         if( (rv = bios_sect_read(disktype-1, c, h, s, loadaddr)) == 0 )
            break;
      if( rv )
      {
         fprintf(stderr, "Error reading sector %d, (%d)\n", sectno, rv/256);
         memset(loadaddr, '\0', 512);
       return -1;
      }
      return 0;
   }
   if( disktype )
   {
      int tries, rv;

      for(tries=0; tries<6; tries++)
         if( (rv = dos_sect_read(disktype-1, sectno, loadaddr)) == 0 )
            break;
      if( rv )
      {
         fprintf(stderr, "Error reading sector %d, (0x%04d)\n", sectno, rv);
         memset(loadaddr, '\0', 512);
       return -1;
      }
      return 0;
   }
#endif
   if( disktype )
   {
      fprintf(stderr, "Cannot read sector %d\n", sectno);
      return -1;
   }
   fseek(diskfd, (long)sectno*512, 0);
   if( (cc=fread(loadaddr, 1, 512, diskfd)) != 512 )
   {
      fprintf(stderr, "Cannot read sector %d, clearing\n", sectno);
      if(cc<0) cc=0;
      memset(loadaddr+cc, '\0', 512-cc);
   }
   return 0;
}

/**************************************************************************/

#ifdef __MSDOS__
bios_sect_read(drv, track, head, sector, loadaddr)
{
#asm
  push      bp
  mov bp,sp

  push      ds
  pop es

  mov dh,[bp+2+_bios_sect_read.head]
  mov dl,[bp+2+_bios_sect_read.drv]
  mov cl,[bp+2+_bios_sect_read.sector]
  mov ch,[bp+2+_bios_sect_read.track]

  mov bx,[bp+2+_bios_sect_read.loadaddr]

  mov ax,#$0201
  int $13
  jc  bios_read_err
  mov ax,#0
bios_read_err:

  pop bp
#endasm
}

bios_sect_write(drv, track, head, sector, loadaddr)
{
#asm
  push      bp
  mov bp,sp

  push      ds
  pop es

  mov dh,[bp+2+_bios_sect_write.head]
  mov dl,[bp+2+_bios_sect_write.drv]
  mov cl,[bp+2+_bios_sect_write.sector]
  mov ch,[bp+2+_bios_sect_write.track]

  mov bx,[bp+2+_bios_sect_write.loadaddr]

  mov ax,#$0301
  int $13
  jc  bios_write_err
  mov ax,#0
bios_write_err:

  pop bp
#endasm
}
#endif

/**************************************************************************/

#ifdef __MSDOS__

/* All this mess just to read one sector!! */

struct disk_packet {
   long     sector;
   int      count;
   long     addr;
} disk_packet;

dos_sect_read(drv, sector, loadaddr)
{
#asm
  push      bp
  mov bp,sp

  mov al,[bp+2+_dos_sect_read.drv]
  mov cx,#1
  mov dx,[bp+2+_dos_sect_read.sector]
  mov bx,[bp+2+_dos_sect_read.loadaddr]

  int $25
  pop bx
  jnc dos_read_ok

  mov bp,sp

  ! Fill the disk packet
  mov ax,[bp+2+_dos_sect_read.sector]
  mov [_disk_packet],ax
  xor ax,ax
  mov [_disk_packet+2],ax
  inc ax
  mov [_disk_packet+4],ax
  mov ax,[bp+2+_dos_sect_read.loadaddr]
  mov [_disk_packet+6],ax
  mov ax,ds
  mov [_disk_packet+8],ax

  mov dl,[bp+2+_dos_sect_read.drv]
  inc dl
  mov bx,#_disk_packet
  mov cx,#0xFFFF
  mov si,#0
  mov ax,#0x7305

  int $21

  jc  dos_read_err
dos_read_ok:
  mov ax,#0
dos_read_err:

  pop bp
#endasm
}

dos_sect_write(drv, sector, loadaddr)
{
#asm
  push      bp
  mov bp,sp

  mov al,[bp+2+_dos_sect_write.drv]
  mov cx,#1
  mov dx,[bp+2+_dos_sect_write.sector]
  mov bx,[bp+2+_dos_sect_write.loadaddr]

  int $26
  pop bx
  jnc dos_write_ok

  mov bp,sp

  ! Fill the disk packet
  mov ax,[bp+2+_dos_sect_write.sector]
  mov [_disk_packet],ax
  xor ax,ax
  mov [_disk_packet+2],ax
  inc ax
  mov [_disk_packet+4],ax
  mov ax,[bp+2+_dos_sect_write.loadaddr]
  mov [_disk_packet+6],ax
  mov ax,ds
  mov [_disk_packet+8],ax

  mov dl,[bp+2+_dos_sect_write.drv]
  inc dl
  mov bx,#_disk_packet
  mov cx,#0xFFFF
  mov si,#1
  mov ax,#0x7305

  int $21

  jc  dos_write_err
dos_write_ok:
  mov ax,#0
dos_write_err:

  pop bp
#endasm
}
#endif
/**************************************************************************/

check_zapped()
{
   int i;
   for(i=0; i<512; i++)
      if( buffer[i] )
         break;

   if( i != 512 )
   {
      fprintf(stderr, "Boot block isn't empty, zap it first\n");
      if(!force) exit(1);
   }
}

/**************************************************************************/

struct tar_head {
   char name[100];
   char mode[8];
   char uid[8];
   char gid[8];
   char size[12];
   char mtime[12];
   char chksum[8];
   char linkflag;
   char linkname[100];
   char magic[8];
   char uname[32];
   char gname[32];
   char devmajor[8];
   char devminor[8];
   char padding[167];
} ;

#define buff_tar  (*(struct tar_head*) buffer)
#define boot_tar  (*(struct tar_head*) tarboot_data)

unsigned int oct(s)
char *s;
{
   unsigned int val = 0;
   int i;
   for(i=0; i<8; i++) if( s[i] >= '0' && s[i] <= '7' )
      val = (val<<3) + s[i] - '0';
   return val;
}

check_tar()
{
   char vbuf[100];
   unsigned char *p;
   unsigned int csum = 0;
   long osum = -1;

   for(p=buffer; p<buffer+512; p++)
      if( *p ) goto not_zapped;
   /* Block zapped, ok */
   return 0;
not_zapped:

   osum = oct(buff_tar.chksum);
   memset(buff_tar.chksum, ' ', sizeof(buff_tar.chksum));

   for(p=buffer; p<buffer+512; p++)
      csum += (*p & 0xFF);

   if( csum != osum )
   {
      fprintf(stderr, "TAR file checksum failed, this isn't a tar file.\n");
      if(!force) exit(9);

      write_one = 1;
      memset(buffer, '\0', 1024);
   }
   if( buff_tar.linkflag != 'V' )
   {
      fprintf(stderr, "Tar file doesn't start with a volume label\n");
      if(!force) exit(8);
   }

   strcpy(vbuf, boot_tar.name); strcat(vbuf, " Volume 1");
   if( strcmp(boot_tar.name, buff_tar.name) != 0 
    && strcmp(vbuf, buff_tar.name) != 0 )
   {
      fprintf(stderr, "WARNING: Volume is labeled as '%s' not '%s'\n",
                       buff_tar.name, boot_tar.name);
   }
   return 0;
}

copy_tarblock()
{
   char lbuf[20];
   unsigned char * p;
   unsigned int csum = 0;
   int i;

   struct tar_head temp;

   temp = boot_tar;

   /* Copy preserved fields
    */
   if( buff_tar.name[0] )
   {
      memcpy(temp.mtime, buff_tar.mtime, sizeof(temp.mtime));

      memset(temp.name, 0x90, 16);
      for(i=0; buff_tar.name[i] && buff_tar.name[i] != ' ' && i<14; i++)
      {
         int ch = buff_tar.name[i];
         if( islower(ch) ) ch = toupper(ch);
         if( strchr("/?@ABCDEFGHIJKLMNO", ch) == 0 )
            ch = '?';
         temp.name[i] = ch;
      }
      temp.name[i++] = 0;
      temp.name[i]   = 0xC0;
   }
   else
      sprintf(temp.mtime, "%11lo", time((void*)0));

   buff_tar = temp;

   /* Re-calculate the checksum */
   memset(buff_tar.chksum, ' ', sizeof(buff_tar.chksum));

   for(p=buffer; p<buffer+512; p++)
      csum += (*p & 0xFF);

   sprintf(buff_tar.chksum, "%7o", csum);

   printf("Boot block installed");
   if( ((struct tar_head*)buffer)[1].name[0] )
      printf(" to boot file '%s'\n",
         ((struct tar_head*)buffer)[1].name);
   else
      printf(", use 'tar -r' to add executable\n");
}

/**************************************************************************/

#define DOS_SYSID 0
#define DOS_SECT  1
#define DOS_CLUST 2
#define DOS_RESV  3
#define DOS_NFAT  4
#define DOS_NROOT 5
#define DOS_MAXSECT     6
#define DOS_MEDIA 7
#define DOS_FATLEN      8
#define DOS_SPT         9
#define DOS_HEADS 10
#define DOS_HIDDEN      11

#define DOS4_MAXSECT    12
#define DOS4_PHY_DRIVE  13
#define DOS4_SERIAL     14
#define DOS4_LABEL      15
#define DOS4_FATTYPE    16

#define DOS7_MAXSECT    17
#define DOS7_FAT32LEN   18
#define DOS7_FLAGS      19
#define DOS7_VERSION    20
#define DOS7_ROOT_CLUST 21
#define DOS7_INFO_SECT  22
#define DOS7_BOOT2      23

struct bootfields {
   int offset;
   int length;
   unsigned value;
   long lvalue;
}
   dosflds[] =
{
   { 0x03, 8, 0},
   { 0x0B, 2, 0},
   { 0x0D, 1, 0},
   { 0x0E, 2, 0},
   { 0x10, 1, 0},
   { 0x11, 2, 0},
   { 0x13, 2, 0},
   { 0x15, 1, 0},
   { 0x16, 2, 0},
   { 0x18, 2, 0},
   { 0x1A, 2, 0},
   { 0x1C, 4, 0},

   { 0x20, 4, 0}, /* DOS4+ */
   { 0x24, 1, 0},
   { 0x27, 4, 0},
   { 0x2B, 11, 0},
   { 0x36, 8, 0},

   { 0x20, 4, 0}, /* DOS7 FAT32 */
   { 0x24, 4, 0},
   { 0x28, 2, 0},
   { 0x2A, 2, 0},
   { 0x2C, 4, 0},
   { 0x30, 2, 0},
   { 0x32, 2, 0},

   { 0x40, 1, 0},
   { 0x43, 4, 0},
   { 0x47, 11, 0},
   { 0x52, 8, 0},

   { 0x3e8, 4, 0},
   { 0x3ec, 4, 0},

   { -1,0,0}
};

print_super(bootsect)
char * bootsect;
{
static char * fieldnames[] = {
   "System ID",
   "Sector size",
   "Cluster size",
   "Reserved sectors",
   "FAT count",
   "Root dir entries",
   "Sector count",
   "Media code",
   "FAT length",
   "Sect/Track",
   "Heads",
   "Hidden sectors (Partition offset)",

   "Large Filesystem sector count",
   "Phys drive",
   "Serial number",
   "Disk Label (DOS 4+)",
   "FAT type",

   "Large Filesystem sector count",
   "FAT32 FAT length",
   "FAT32 Flags",
   "FAT32 version",
   "FAT32 Root Cluster",
   "FAT32 Info Sector",
   "FAT32 Backup Boot",

   "FAT32 Phys Drive",
   "FAT32 Serial number",
   "FAT32 Disk Label",
   "FAT32 FAT Type",

   "FAT32 Free clusters",
   "FAT32 Next free cluster",

   0
};
   int i;
   long numclust = 0xFFFF;
   int fatbits = 0;
   int fat_len = -1;

   for(i=0; dosflds[i].offset >= 0; i++)
   {
      if( i>= DOS4_MAXSECT && (fat_len==0) != (i>=DOS7_MAXSECT) )
       continue;

      if( dosflds[i].length <= 4 )
      {
         long v = 0; int j;
       for(j=dosflds[i].length-1; j>=0; j--)
       {
          v = v*256 + (0xFF&( bootsect[dosflds[i].offset+j] ));
       }

       if( i==DOS_FATLEN )
          fat_len = v;

       if (v==0 && 
        (i==DOS_FATLEN || i==DOS_MAXSECT || i==DOS4_MAXSECT || i==DOS_NROOT))
          continue;

         printf("%-35s%ld\n", fieldnames[i], v);

       if (i==DOS_SECT && v!=512 && v!=1024 && v!=2048)
          break;
      }
      else
      {
         int ch, j;
         printf("%-35s", fieldnames[i]);
       for(j=0; j<dosflds[i].length; j++)
       {
          ch = bootsect[dosflds[i].offset+j];
          if( ch < ' ' || ch > '~' ) putchar('.');
          else                       putchar(ch);
       }
       putchar('\n');
      }
   }
}

decode_super(bootsect)
char * bootsect;
{
   int i;

   for(i=0; dosflds[i].offset >= 0; i++)
   {
      if( i>= DOS4_MAXSECT && 
          (dosflds[DOS_FATLEN].value==0) != (i>=DOS7_MAXSECT) )
      {
       dosflds[i].lvalue = dosflds[i].value = 0;
       continue;
      }

      if( dosflds[i].length <= 4 )
      {
         long v = 0; int j;
       for(j=dosflds[i].length-1; j>=0; j--)
       {
          v = v*256 + (0xFF&( bootsect[dosflds[i].offset+j] ));
       }
       dosflds[i].value = v;
       dosflds[i].lvalue = v;
      }
      else
       dosflds[i].lvalue = dosflds[i].value = 0;
   }
}

save_super(bootsect)
char * bootsect;
{
   FILE * fd;
   char * fname = "makeboot.sav";
   if( boot_id ) fname = boot_id;

   printf("Copying boot block to '%s'\n", fname);
   fd = fopen(fname, "wb");
   fwrite(bootsect, 1024, 1, fd);
   fclose(fd);
}

/**************************************************************************/

check_msdos()
{
   decode_super(buffer);
   if( dosflds[DOS_CLUST].value == 0 )    /* MSDOS v1.0 */
      dosflds[DOS_CLUST].value = 1;

   if( dosflds[DOS_MEDIA].value < 0xF0 )
   {
      if (!force)
         fprintf(stderr, "Dos media descriptor is invalid\n");
   }
   else if( dosflds[DOS_MEDIA].value != (0xFF&buffer[512])
         && dosflds[DOS_RESV].value == 1 )
      fprintf(stderr, "Dos media descriptor check failed\n");
   else
   {
      disk_sect = dosflds[DOS_SPT].value;
      disk_head = dosflds[DOS_HEADS].value;
      if( disk_sect > 0 && disk_head > 0 )
         disk_trck = dosflds[DOS_MAXSECT].value/disk_head/disk_sect;

#ifndef __MSDOS__
      if( bs_offset == 0 &&
          memcmp(buffer+dosflds[DOS_SYSID].offset, "2M-STV0", 7) == 0)
      {
         printf("Floppy is in 2M format - reading 2nd boot block\n");
         bs_offset = dosflds[DOS_RESV].value + dosflds[DOS_FATLEN].value;
         if( read_sector(bs_offset, buffer) != 0 )
            exit(1);

         decode_super(buffer);
         if( dosflds[DOS_MEDIA].value < 0xF0 ||
                ( dosflds[DOS_MEDIA].value != (0xFF&buffer[512])
               && dosflds[DOS_RESV].value == 1 ) )
       {
          if( force )
          {
               printf("Bad 2nd boot block - reloading first\n");
               if( read_sector(0, buffer) != 0 )
                  exit(1);
          }
          else
          {
               printf("Bad 2nd boot block\n");
             exit(1);
          }
       }
         check_msdos();
      }
#endif
      return;
   }
   if(!force) exit(2);
}

check_simpledos(bb_fatbits)
int bb_fatbits;
{
   long numclust = 0xFFFF;
   char * err = 0;
   int fatbits = 0;

   /* Work out how many real clusters there are */
   if( dosflds[DOS_MAXSECT].value + 2 > 2 )
      numclust = ( dosflds[DOS_MAXSECT].value
                   - dosflds[DOS_RESV].value
                   - dosflds[DOS_NFAT].value * dosflds[DOS_FATLEN].value
                   - ((dosflds[DOS_NROOT].value+15)/16)
                 ) / dosflds[DOS_CLUST].value + 2;
   else if( dosflds[DOS4_MAXSECT].value > 0 )
      numclust = ( dosflds[DOS4_MAXSECT].lvalue
                   - dosflds[DOS_RESV].value
                   - dosflds[DOS_NFAT].value * dosflds[DOS_FATLEN].value
                   - ((dosflds[DOS_NROOT].value+15)/16)
                 ) / dosflds[DOS_CLUST].value + 2;
   else
      numclust = ( dosflds[DOS7_MAXSECT].lvalue
                   - dosflds[DOS_RESV].value
                   - dosflds[DOS_NFAT].value * dosflds[DOS7_FAT32LEN].value
                 ) / dosflds[DOS_CLUST].value;

   if( memcmp(buffer+dosflds[DOS4_FATTYPE].offset, "FAT12", 5) == 0 )
      fatbits=12;
   else if( memcmp(buffer+dosflds[DOS4_FATTYPE].offset, "FAT16", 5) == 0 )
      fatbits=16;
   else
      fatbits=12+4*(numclust > 0xFF0) + 16*(numclust > 0xFFF0L);

   if( dosflds[DOS_NFAT].value > 2 )
      err = "Too many fat copies on disk";
   else if( dosflds[DOS_NROOT].value < 15 )
      err = "Root directory has unreasonable size.";
   else if( dosflds[DOS_SECT].value != 512 )
      err = "Drive sector size isn't 512 bytes sorry no-go.";
   else if( fatbits == 16 && numclust < 0xFF0 )
      err = "Weirdness, FAT16 but less than $FF0 clusters";
   else if( fatbits != bb_fatbits )
      err = "Filesystem has the wrong fat type for this bootblock.";
   else if( numclust * dosflds[DOS_CLUST].lvalue / 
          dosflds[DOS_SPT].value > 65535 )
      err = "Boot sector untested with more than 65535 tracks";

   if( !err && bb_fatbits == 12 )
   {
      if( dosflds[DOS4_PHY_DRIVE].value != 0 )
         err = "This boot sector is only for floppies";
      else if( (0x7C00-msdos_start-512)/512 < dosflds[DOS_FATLEN].value )
         err = "The FAT is too large to load in the available space.";
      else if( dosflds[DOS_RESV].value + dosflds[DOS_FATLEN].value > 
               dosflds[DOS_SPT].value )
         err = "The bootblock needs all of fat1 on the first track.";
      else if( msdos_heads == 2 && dosflds[DOS_HEADS].value != 2 )
         err = "Drive doesn't have two heads, this is required.";
      else if( dosflds[DOS_HIDDEN].lvalue != 0 )
         err = "MSDOS floppies shouldn't have hidden sectors.";
   }
   
   if( err )
   {
      fprintf(stderr, "ERROR: %s\n\n", err);
      print_super(buffer);
      if(!force) exit(2);
   }
}

set_dosname(boot_name)
int boot_name;
{
   char dos_name[20];
   int i,j;

   strcpy(dos_name, "           ");

   for(i=0; boot_id[i] && boot_id[i] != '.' && i<16; i++)
      dos_name[i] = toupper(boot_id[i]);

   if( boot_id[i] == '.' )
   {
      for(j=8,i++; boot_id[i] && boot_id[i] != '.' && j<16; i++,j++)
         dos_name[j] = toupper(boot_id[i]);
   }

   printf("Bootfile set to '%11.11s'\n", dos_name);

   memcpy(buffer+boot_name, dos_name, 11);
}

set_asciz(boot_name)
int boot_name;
{
   int i, j;

   for(i=boot_name; buffer[i]; i++) ;
   for(           ; !buffer[i]; i++) ;
   i = i - boot_name -1;

   if( strlen(boot_id) > i )
   {
      fprintf(stderr, "Name '%s' is too long for bootblock\n");
      exit(1);
   }
   else
   {
      for(i=0,j=boot_name; boot_id[i]; i++)
      {
       if( boot_id[i] == '\\' && boot_id[i+1] )
       {
          i++;
          switch(boot_id[i])
          {
             case 'n': buffer[j++] = '\n'; break;
             case 'r': buffer[j++] = '\r'; break;
             case 'b': buffer[j++] = '\b'; break;
             case 't': buffer[j++] = '\t'; break;
             case 'a': buffer[j++] = '\007'; break;
             case 'e': buffer[j++] = '\033'; break;
             default:  buffer[j++] = boot_id[i]; break;
          }
       }
#ifdef __MSDOS__
       else if(boot_id[i] == '_')   buffer[j++] = ' ';
       else if(boot_id[i] == '^') { buffer[j++] = '\r'; buffer[j++] = '\n'; }
#endif
       else buffer[j++] = boot_id[i];
      }
      buffer[j] = 0;
   }
}

check_mbr()
{
   int i = 0;

   if( buffer[510] == 0x55 && buffer[511] == 0xAA )
      i = 512;

   for(; i<512; i++)
      if( buffer[i] )
         break;

   /* Check for Disk Manager partition tables */
   if( buffer[252] == 0x55 && buffer[253] == 0xAA )
   {
      if( (unsigned char)mbr_data[252] != 0x55 || 
        (unsigned char)mbr_data[253] != 0xAA )
       i = 252;
   }

   if( i != 512 )
   {
      if(force)
         fprintf(stderr, "That doesn't look like a compatible MBR but ...\n");
      else
      {
         fprintf(stderr, "That doesn't look like a compatible MBR\n");
         exit(1);
      }
   }
}

copy_mbr(mbr_data)
char * mbr_data;
{
   if( buffer[252] != 0xAA || buffer[253] != 0x55 ||
       (unsigned char)mbr_data[252] != 0xAA || mbr_data[253] != 0x55 )
      memcpy(buffer, mbr_data, 446);
   else
      memcpy(buffer, mbr_data, 254);

   buffer[510] = 0x55;
   buffer[511] = 0xAA;
   write_zero = 1;
}

/**************************************************************************/

#ifdef HAS_2M20

char boot_sector_2m_23_82[] = {
0xe9,0x7d,0x00,0x32,0x4d,0x2d,0x53,0x54,0x56,0x30,0x34,0x00,0x02,0x01,0x01,0x00,
0x02,0xe0,0x00,0xbc,0x0e,0xfa,0x0b,0x00,0x17,0x00,0x02,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x29,0x45,0xb8,0x25,0x51,0x4e,0x4f,0x20,0x4e,0x41,
0x4d,0x45,0x20,0x20,0x20,0x20,0x46,0x41,0x54,0x31,0x32,0x20,0x20,0x20,0x00,0x3f,
0x07,0x01,0x00,0x00,0x80,0x00,0x4c,0x00,0x61,0x00,0x79,0x00,0x13,0x46,0x01,0x02,
0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,
0x13,0x40,0x03,0x07,0x81,0x04,0x04,0x8c,0x01,0x04,0x97,0x05,0x04,0xa2,0x02,0x04,
0xad,0x06,0x03,0xb3,0x03,0x04,0xbe,0x07,0x02,0x04,0x04,0x04,0x04,0x04,0x03,0x02,
0xfa,0x33,0xc0,0x8e,0xd0,0xbc,0x00,0x7c,0xb8,0xc0,0x07,0x50,0x05,0x20,0x00,0x50,
0x07,0x1f,0x33,0xf6,0x33,0xff,0xb9,0x00,0x01,0xfc,0xf3,0xa5,0x8b,0x1e,0x44,0x00,
0x8d,0x47,0x26,0x06,0x50,0xcb,0xfb,0xbe,0x1a,0x01,0xe8,0xd9,0x00,0xbb,0x78,0x00,
0x36,0xc5,0x37,0x1e,0x56,0x33,0xff,0x36,0x89,0x3f,0x36,0x8c,0x47,0x02,0xb9,0x0b,
0x00,0xf3,0xa4,0x06,0x1f,0xa0,0x18,0x00,0x88,0x45,0xf9,0x33,0xc0,0x8e,0xc0,0xbb,
0x00,0x7c,0x26,0x89,0x87,0xfe,0x01,0xb8,0x01,0x02,0x8b,0x0e,0x16,0x00,0x83,0xc1,
0x02,0x33,0xd2,0x83,0xf9,0x0a,0x72,0x1f,0x51,0xcd,0x13,0x59,0x36,0x8b,0x1e,0x13,
0x04,0x83,0xeb,0x05,0xb8,0x40,0x00,0xf7,0xe3,0x8e,0xc0,0x53,0x33,0xdb,0xb8,0x05,
0x02,0x41,0x33,0xd2,0xcd,0x13,0x5b,0x36,0x8f,0x06,0x78,0x00,0x36,0x8f,0x06,0x7a,
0x00,0x26,0x81,0x3e,0xfe,0x09,0x55,0xaa,0x75,0x60,0x36,0x89,0x1e,0x13,0x04,0x06,
0xb4,0x08,0xb3,0x00,0xb2,0x00,0xcd,0x13,0x8a,0xc3,0xb4,0x00,0x80,0xfa,0x02,0x72,
0x0c,0x50,0xb4,0x08,0xb3,0x00,0xb2,0x01,0xcd,0x13,0x58,0x8a,0xe3,0x07,0x26,0x8c,
0x06,0xfe,0x09,0x26,0xff,0x1e,0xfc,0x09,0xb8,0x01,0x02,0x33,0xd2,0x8e,0xc2,0xb9,
0x01,0x00,0xbb,0x00,0x80,0x50,0xcd,0x13,0x58,0xbb,0x00,0x7c,0x06,0x53,0x26,0x81,
0x7f,0x03,0x32,0x4d,0x75,0x04,0xb2,0x80,0xcd,0x13,0x26,0x81,0x3e,0xfe,0x7d,0x55,
0xaa,0x75,0x03,0x33,0xd2,0xcb,0x22,0xd2,0x74,0xec,0xbe,0x2f,0x01,0xe8,0x06,0x00,
0xb4,0x00,0xcd,0x16,0xcd,0x19,0x03,0x36,0x44,0x00,0xfc,0xac,0x22,0xc0,0x74,0x09,
0xb4,0x0e,0xbb,0x07,0x00,0xcd,0x10,0xeb,0xf1,0xc3,0x0d,0x0a,0x32,0x4d,0x20,0x53,
0x75,0x70,0x65,0x72,0x42,0x4f,0x4f,0x54,0x20,0x32,0x2e,0x30,0x0d,0x0a,0x00,0x0d,
0x0a,0xad,0x4e,0x6f,0x20,0x62,0x6f,0x74,0x61,0x62,0x6c,0x65,0x21,0x0d,0x0a,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x4d,0x61,0x64,0x65,0x20,0x69,0x6e,0x20,0x53,0x70,0x61,0x69,0x6e,0x00,0x55,0xaa
};

char boot_sector_2m_22_82[] = {
0xe9,0x6e,0x00,0x32,0x4d,0x2d,0x53,0x54,0x56,0x30,0x38,0x00,0x02,0x01,0x01,0x00,
0x02,0xe0,0x00,0x18,0x0e,0xfa,0x0b,0x00,0x16,0x00,0x02,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x29,0xcc,0x9b,0xe1,0xd4,0x4e,0x4f,0x20,0x4e,0x41,
0x4d,0x45,0x20,0x20,0x20,0x20,0x46,0x41,0x54,0x31,0x32,0x20,0x20,0x20,0x00,0x04,
0x07,0x00,0x00,0x00,0x71,0x00,0x4c,0x00,0x61,0x00,0x66,0x00,0x13,0x46,0x01,0x02,
0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,
0x13,0x0b,0x28,0x03,0x01,0x02,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,
0x03,0xfa,0x33,0xc0,0x8e,0xd0,0xbc,0x00,0x7c,0xb8,0xc0,0x07,0x50,0x05,0x20,0x00,
0x50,0x07,0x1f,0x33,0xf6,0x33,0xff,0xb9,0x00,0x01,0xfc,0xf3,0xa5,0x8b,0x1e,0x44,
0x00,0x8d,0x47,0x26,0x06,0x50,0xcb,0xfb,0xbe,0x1a,0x01,0xe8,0xd9,0x00,0xbb,0x78,
0x00,0x36,0xc5,0x37,0x1e,0x56,0x33,0xff,0x36,0x89,0x3f,0x36,0x8c,0x47,0x02,0xb9,
0x0b,0x00,0xf3,0xa4,0x06,0x1f,0xa0,0x18,0x00,0x88,0x45,0xf9,0x33,0xc0,0x8e,0xc0,
0xbb,0x00,0x7c,0x26,0x89,0x87,0xfe,0x01,0xb8,0x01,0x02,0x8b,0x0e,0x16,0x00,0x83,
0xc1,0x02,0x33,0xd2,0x83,0xf9,0x0a,0x72,0x1f,0x51,0xcd,0x13,0x59,0x36,0x8b,0x1e,
0x13,0x04,0x83,0xeb,0x05,0xb8,0x40,0x00,0xf7,0xe3,0x8e,0xc0,0x53,0x33,0xdb,0xb8,
0x05,0x02,0x41,0x33,0xd2,0xcd,0x13,0x5b,0x36,0x8f,0x06,0x78,0x00,0x36,0x8f,0x06,
0x7a,0x00,0x26,0x81,0x3e,0xfe,0x09,0x55,0xaa,0x75,0x60,0x36,0x89,0x1e,0x13,0x04,
0x06,0xb4,0x08,0xb3,0x00,0xb2,0x00,0xcd,0x13,0x8a,0xc3,0xb4,0x00,0x80,0xfa,0x02,
0x72,0x0c,0x50,0xb4,0x08,0xb3,0x00,0xb2,0x01,0xcd,0x13,0x58,0x8a,0xe3,0x07,0x26,
0x8c,0x06,0xfe,0x09,0x26,0xff,0x1e,0xfc,0x09,0xb8,0x01,0x02,0x33,0xd2,0x8e,0xc2,
0xb9,0x01,0x00,0xbb,0x00,0x80,0x50,0xcd,0x13,0x58,0xbb,0x00,0x7c,0x06,0x53,0x26,
0x81,0x7f,0x03,0x32,0x4d,0x75,0x04,0xb2,0x80,0xcd,0x13,0x26,0x81,0x3e,0xfe,0x7d,
0x55,0xaa,0x75,0x03,0x33,0xd2,0xcb,0x22,0xd2,0x74,0xec,0xbe,0x2f,0x01,0xe8,0x06,
0x00,0xb4,0x00,0xcd,0x16,0xcd,0x19,0x03,0x36,0x44,0x00,0xfc,0xac,0x22,0xc0,0x74,
0x09,0xb4,0x0e,0xbb,0x07,0x00,0xcd,0x10,0xeb,0xf1,0xc3,0x0d,0x0a,0x32,0x4d,0x20,
0x53,0x75,0x70,0x65,0x72,0x42,0x4f,0x4f,0x54,0x20,0x32,0x2e,0x30,0x0d,0x0a,0x00,
0x0d,0x0a,0xad,0x4e,0x6f,0x20,0x62,0x6f,0x74,0x61,0x62,0x6c,0x65,0x21,0x0d,0x0a,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x4d,0x61,0x64,0x65,0x20,0x69,0x6e,0x20,0x53,0x70,0x61,0x69,0x6e,0x00,0x55,0xaa
};


char program_2m_vsn_20[] = {
0x2b,0x00,0x43,0x00,0x32,0x30,0x32,0x4d,0x2d,0x53,0x54,0x56,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0a,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x46,0x4a,0x42,0x00,0x00,0x01,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfb,0xfc,0x9c,0x56,0x80,
0xfa,0x02,0x73,0x3d,0xe8,0x41,0x00,0x2e,0x80,0x3c,0x02,0x74,0x04,0x2e,0x80,0x3c,
0x04,0x72,0x2e,0x80,0xfc,0x02,0x72,0x29,0x80,0xfc,0x05,0x77,0x24,0x75,0x05,0xe8,
0x36,0x00,0xeb,0x1d,0xe8,0x85,0x00,0x73,0x09,0x5e,0x9d,0xf9,0xb8,0x00,0x06,0xca,
0x02,0x00,0x2e,0x80,0x7c,0x01,0x00,0x74,0x08,0x5e,0x9d,0xe8,0x3c,0x02,0xca,0x02,
0x00,0x5e,0x9d,0x2e,0xff,0x2e,0xfc,0x09,0x9c,0x53,0x8a,0xda,0xb7,0x00,0xd1,0xe3,
0x2e,0x8b,0xb7,0x00,0x00,0x5b,0x9d,0xc3,0x60,0xe8,0xec,0xff,0xb0,0x01,0x72,0x02,
0xb0,0x00,0x2e,0x88,0x44,0x01,0x61,0xc3,0x50,0xa0,0x12,0x00,0x0a,0x06,0x11,0x00,
0x58,0xc3,0x60,0x1e,0x6a,0x40,0x1f,0xb0,0x01,0x8a,0xca,0xd2,0xe0,0x84,0x06,0x3f,
0x00,0x75,0x04,0xf8,0xe8,0xef,0x05,0x8a,0xe2,0xc0,0xe4,0x04,0x0a,0xe0,0xc0,0xe0,
0x04,0x0c,0x0c,0x0a,0xc2,0xba,0xf2,0x03,0xfa,0x88,0x26,0x3f,0x00,0xee,0x83,0xc2,
0x05,0xeb,0x00,0xeb,0x00,0xec,0xfb,0xa8,0x80,0x1f,0x61,0xc3,0x60,0xe8,0x98,0xff,
0x2e,0x80,0x7c,0x02,0x01,0x2e,0xc6,0x44,0x02,0x00,0x74,0x08,0xe8,0xb3,0xff,0x75,
0x03,0x61,0xf8,0xc3,0xf8,0xe8,0x90,0xff,0x1e,0x06,0xbb,0x90,0x00,0x02,0xda,0x6a,
0x40,0x1f,0x80,0x27,0xef,0x0e,0x0e,0x1f,0x07,0x88,0x16,0x0c,0x00,0xf9,0xe8,0x29,
0x05,0xc6,0x06,0x11,0x00,0x01,0xc6,0x06,0x12,0x00,0x00,0xe8,0xa1,0x05,0xfe,0x0e,
0x11,0x00,0xe8,0x9a,0x05,0xf8,0xe8,0x7d,0x05,0xe8,0x76,0xff,0x74,0x07,0xc6,0x44,
0x02,0x01,0xf8,0xeb,0x68,0x1e,0x6a,0x40,0x1f,0xc6,0x06,0x41,0x00,0x06,0x1f,0xc6,
0x06,0x1b,0x00,0xff,0xc6,0x44,0x08,0x14,0xb9,0x03,0x00,0x51,0x83,0xf9,0x02,0xe8,
0xe8,0x04,0xc6,0x44,0x06,0x00,0xc6,0x06,0x11,0x00,0x00,0xc6,0x06,0x12,0x00,0x00,
0xc6,0x06,0x13,0x00,0x01,0xc6,0x06,0x16,0x00,0x00,0xc6,0x06,0x17,0x00,0x01,0xc6,
0x06,0x27,0x00,0x46,0x8b,0x3e,0x19,0x00,0xe8,0x7f,0x02,0x75,0x0b,0x59,0x8b,0x1e,
0x19,0x00,0xe8,0x1c,0x00,0xf8,0xeb,0x14,0x8a,0x44,0x06,0x40,0x3c,0x03,0x77,0x05,
0x88,0x44,0x06,0xeb,0xc1,0xc6,0x44,0x06,0x00,0x59,0xe2,0xaf,0xf9,0x07,0x1f,0x61,
0xc3,0x60,0xe8,0x88,0x00,0x72,0x5c,0x88,0x44,0x05,0x88,0x4c,0x03,0x8a,0x16,0x0c,
0x00,0xf9,0xe8,0xd3,0xfe,0x26,0x8a,0x47,0x16,0x88,0x44,0x17,0x26,0x8a,0x4f,0x41,
0x88,0x4c,0x04,0x26,0x8b,0x47,0x42,0x89,0x44,0x06,0x26,0x8a,0x47,0x18,0x88,0x44,
0x09,0x26,0x8b,0x7f,0x48,0x26,0x8a,0x41,0x01,0x8a,0xe0,0x22,0xc9,0x74,0x0a,0x80,
0xc4,0xbe,0xb0,0x0b,0xf6,0xe4,0x2d,0x3e,0x08,0xd0,0xe8,0x88,0x44,0x08,0xb9,0x0d,
0x00,0x26,0x8b,0x7f,0x4a,0x03,0xfb,0x8d,0x5c,0x0a,0x26,0x8a,0x05,0x88,0x07,0x43,
0x47,0xe2,0xf7,0x8a,0x44,0x06,0xc0,0xe0,0x06,0x0c,0x17,0x80,0x3c,0x02,0x77,0x0a,
0x24,0xf8,0x0c,0x05,0xa8,0x40,0x74,0x02,0x34,0x21,0x1e,0xbb,0x90,0x00,0x02,0x1e,
0x0c,0x00,0x6a,0x40,0x1f,0x80,0x27,0x08,0x08,0x07,0x1f,0x61,0xc3,0x56,0x57,0x8d,
0x7f,0x03,0xbe,0x06,0x00,0xb9,0x06,0x00,0xf3,0xa6,0xf9,0x75,0x19,0x33,0xc0,0x26,
0x8a,0x4f,0x40,0x80,0xf9,0x06,0x72,0x0d,0x26,0x8b,0x7f,0x44,0x4f,0x26,0x02,0x01,
0x83,0xff,0x3f,0x77,0xf7,0xf8,0x5f,0x5e,0xc3,0x50,0x73,0x37,0x80,0x3e,0x1f,0x00,
0x00,0x75,0x2f,0xa0,0x21,0x00,0xd0,0xe0,0xb4,0x04,0x72,0x22,0xc0,0xe0,0x02,0xb4,
0x10,0x72,0x1b,0xd0,0xe0,0xb4,0x08,0x72,0x15,0xc0,0xe0,0x02,0xb4,0x04,0x72,0x0e,
0xd0,0xe0,0xb4,0x03,0x72,0x08,0xd0,0xe0,0xb4,0x02,0x72,0x02,0xb4,0x20,0x08,0x26,
0x1f,0x00,0xf9,0x58,0xc3,0x9c,0x60,0x06,0x6a,0x40,0x07,0xbf,0x41,0x00,0xbe,0x1f,
0x00,0xb9,0x04,0x00,0xf3,0xa5,0x07,0x61,0x9d,0xc3,0x1e,0x60,0x0e,0x1f,0x88,0x16,
0x0c,0x00,0xe8,0xc3,0xfd,0x80,0x7c,0x05,0x00,0x74,0x08,0xc6,0x06,0x1f,0x00,0x40,
0xe9,0xbb,0x00,0x50,0xb4,0x00,0xa3,0x0d,0x00,0x8a,0xc5,0xd0,0xe0,0x8a,0xd6,0x80,
0xe6,0x7f,0x02,0xc6,0xf6,0x64,0x09,0x02,0xc1,0x80,0xd4,0x00,0x48,0xa3,0x0f,0x00,
0x8b,0xfb,0x5b,0x8a,0xdf,0xb7,0x00,0x8a,0x8f,0x26,0x00,0x88,0x0e,0x27,0x00,0xd0,
0xe2,0x72,0x73,0x23,0xc0,0x75,0x2c,0x80,0x7c,0x03,0x07,0x72,0x19,0x8a,0x44,0x17,
0x40,0xb9,0x01,0x00,0xe8,0x9b,0x00,0x75,0x6e,0xff,0x0e,0x0d,0x00,0xff,0x06,0x0f,
0x00,0xa1,0x0f,0x00,0xeb,0x0d,0x80,0x3e,0x27,0x00,0x4a,0x75,0x06,0x81,0xc7,0x00,
0x02,0xeb,0xe6,0x8a,0x4c,0x17,0xb5,0x00,0x3b,0xc1,0x77,0x0f,0xe8,0x5d,0x00,0xe8,
0x70,0x00,0x75,0x43,0x83,0x3e,0x0d,0x00,0x00,0x74,0x3c,0xa1,0x0f,0x00,0x8a,0x4c,
0x17,0xb5,0x00,0xd1,0xe1,0x3b,0xc1,0x77,0x1d,0xe8,0x40,0x00,0x80,0x3e,0x27,0x00,
0x4a,0x75,0x07,0xc1,0xe1,0x09,0x03,0xf9,0xeb,0x0c,0x8a,0x54,0x17,0xb6,0x00,0x2b,
0xc2,0xe8,0x3e,0x00,0x75,0x11,0x83,0x3e,0x0d,0x00,0x00,0x74,0x0a,0xa1,0x0f,0x00,
0x8b,0x0e,0x0d,0x00,0xe8,0x2b,0x00,0xf8,0xe8,0x2b,0x03,0xe8,0x17,0xff,0x61,0x8a,
0x26,0x1f,0x00,0x1f,0x22,0xe4,0x74,0x03,0xf9,0xb0,0x00,0xc3,0x2b,0xc8,0x41,0x3b,
0x0e,0x0d,0x00,0x76,0x04,0x8b,0x0e,0x0d,0x00,0x29,0x0e,0x0d,0x00,0x01,0x0e,0x0f,
0x00,0xc3,0x8b,0xd8,0x88,0x0e,0x17,0x00,0xf6,0x74,0x09,0xfe,0xc4,0x88,0x26,0x13,
0x00,0xd0,0xe8,0xa2,0x11,0x00,0xd0,0xd0,0x24,0x01,0xa2,0x12,0x00,0xa0,0x13,0x00,
0x02,0x06,0x17,0x00,0x72,0x06,0x48,0x3a,0x44,0x09,0x76,0x07,0xc6,0x06,0x1f,0x00,
0x04,0xeb,0x77,0x8a,0xc4,0x98,0xe8,0xbf,0xfc,0x74,0x18,0x8d,0x5c,0x09,0x48,0x43,
0xfe,0xc4,0x8a,0x0f,0x80,0xe9,0x02,0xb5,0x01,0xd2,0xe5,0x2a,0xc5,0x73,0xf0,0x02,
0xc5,0x86,0xe0,0xa2,0x13,0x00,0x88,0x26,0x16,0x00,0xe8,0xe8,0x01,0xb4,0x00,0x88,
0x26,0x15,0x00,0xe8,0x92,0xfc,0x75,0x09,0xa0,0x17,0x00,0x88,0x26,0x17,0x00,0xeb,
0x28,0x38,0x64,0x04,0x75,0x28,0x38,0x26,0x16,0x00,0x74,0x05,0xe8,0x31,0x00,0x72,
0x29,0x38,0x26,0x17,0x00,0x74,0x23,0xe8,0x9b,0x01,0x8a,0xc8,0xa0,0x17,0x00,0xf6,
0xf1,0x22,0xc0,0x74,0x09,0x88,0x26,0x17,0x00,0xe8,0x82,0x00,0x72,0x0c,0x80,0x3e,
0x17,0x00,0x00,0x74,0x05,0xe8,0x08,0x00,0x73,0xf4,0x80,0x3e,0x1f,0x00,0x00,0xc3,
0x50,0x80,0x3e,0x27,0x00,0x4a,0x74,0x16,0x80,0x3e,0x27,0x00,0x42,0x74,0x3b,0xe8,
0xbb,0x00,0x73,0x05,0xe8,0xdb,0x00,0x72,0x48,0xe8,0x6f,0x00,0xeb,0x43,0x80,0x3e,
0x16,0x00,0x00,0x75,0x09,0xe8,0x4d,0x01,0x38,0x06,0x17,0x00,0x73,0x14,0xe8,0x9c,
0x00,0x73,0x0f,0xc6,0x06,0x27,0x00,0x46,0xe8,0xb7,0x00,0xc6,0x06,0x27,0x00,0x4a,
0x72,0x1f,0xe8,0x46,0x00,0xe8,0xaa,0x00,0xeb,0x17,0x53,0x8a,0x1e,0x16,0x00,0xe8,
0x23,0x01,0xfe,0x0e,0x17,0x00,0x74,0x05,0x43,0x3a,0xd8,0x72,0xf5,0x5b,0xe8,0x91,
0x00,0x9c,0xfe,0x06,0x13,0x00,0xc6,0x06,0x16,0x00,0x00,0x9d,0x58,0xc3,0x50,0x22,
0xc0,0x74,0x16,0x8a,0x26,0x13,0x00,0x88,0x26,0x14,0x00,0x02,0xc4,0x48,0xa2,0x15,
0x00,0xfe,0xc0,0xe8,0x6c,0x00,0xa2,0x13,0x00,0x58,0xc3,0x50,0x53,0x51,0x56,0x8a,
0x1e,0x16,0x00,0xe8,0xdf,0x00,0x53,0xc1,0xe3,0x09,0x03,0x1e,0x19,0x00,0x8b,0xf3,
0xb9,0x00,0x01,0xe8,0x16,0x00,0xf3,0xa5,0xe8,0x11,0x00,0x5b,0xfe,0x0e,0x17,0x00,
0x74,0x05,0x43,0x3a,0xd8,0x72,0xdf,0x5e,0x59,0x5b,0x58,0xc3,0x2e,0x80,0x3e,0x27,
0x00,0x4a,0x74,0x02,0xf8,0xc3,0x87,0xf7,0x06,0x1e,0x07,0x1f,0xc3,0x50,0xa0,0x1b,
0x00,0x3a,0x06,0x0c,0x00,0x75,0x18,0xa0,0x11,0x00,0x8a,0x26,0x12,0x00,0x3b,0x06,
0x1c,0x00,0x75,0x0b,0xa0,0x1e,0x00,0x3a,0x06,0x13,0x00,0x75,0x02,0x58,0xc3,0xf9,
0x58,0xc3,0x50,0x53,0xe8,0x78,0x01,0x73,0x0f,0x80,0x3e,0x1f,0x00,0x00,0x75,0x05,
0x80,0x0e,0x1f,0x00,0x40,0xf9,0xeb,0x6a,0xe8,0x3d,0xfb,0xb0,0x02,0x74,0x0d,0x8d,
0x5c,0x0a,0x02,0x1e,0x13,0x00,0x80,0xd7,0x00,0x8a,0x47,0xff,0xa2,0x18,0x00,0x80,
0x3e,0x15,0x00,0x00,0x74,0x0b,0xe8,0x5c,0x02,0xc6,0x06,0x15,0x00,0x00,0x9c,0xeb,
0x3d,0x06,0x57,0x0e,0x07,0x8b,0x3e,0x19,0x00,0xa0,0x13,0x00,0xa2,0x14,0x00,0xa2,
0x15,0x00,0xe8,0x40,0x02,0xc6,0x06,0x15,0x00,0x00,0x5f,0x07,0x9c,0xb0,0xff,0x72,
0x0a,0x80,0x3e,0x27,0x00,0x42,0x74,0x16,0xa0,0x0c,0x00,0xa2,0x1b,0x00,0xa0,0x11,
0x00,0x8a,0x26,0x12,0x00,0xa3,0x1c,0x00,0xa0,0x13,0x00,0xa2,0x1e,0x00,0x9d,0xe8,
0x97,0xfc,0x5b,0x58,0xc3,0xe8,0xd0,0xfa,0xb0,0x01,0x74,0x18,0x53,0x51,0x8d,0x5c,
0x0a,0x02,0x1e,0x13,0x00,0x80,0xd7,0x00,0x8a,0x4f,0xff,0x80,0xe9,0x02,0xb0,0x01,
0xd2,0xe0,0x59,0x5b,0xc3,0x60,0x1e,0xbb,0x40,0x00,0x53,0x1f,0xb5,0xed,0xfa,0x2e,
0x8a,0x0e,0x0c,0x00,0xb0,0x01,0xd2,0xe0,0x84,0x47,0xff,0x74,0x04,0x38,0x2f,0x76,
0x33,0x08,0x47,0xff,0x80,0x67,0xff,0xcf,0x8a,0xc1,0xc0,0xe0,0x04,0x08,0x47,0xff,
0xc6,0x07,0xff,0xfb,0xba,0xf2,0x03,0x80,0xc1,0x04,0xb0,0x01,0xd2,0xe0,0x2e,0x0a,
0x06,0x0c,0x00,0x0c,0x0c,0xee,0xb8,0xfd,0x90,0xf8,0xcd,0x15,0x72,0x06,0xb8,0xe8,
0x03,0xe8,0x48,0x03,0x88,0x2f,0xfb,0x1f,0x61,0xc3,0x60,0xe8,0x68,0x00,0x8a,0x0e,
0x0c,0x00,0x8a,0xc1,0xc0,0xe0,0x02,0x0c,0x01,0xd2,0xe0,0x1e,0x6a,0x40,0x1f,0xfa,
0xa2,0x3f,0x00,0x80,0x26,0x3e,0x00,0x70,0x1f,0xc0,0xe0,0x04,0x0a,0xc1,0x0c,0x08,
0xba,0xf2,0x03,0xee,0xe8,0x08,0x03,0x0c,0x04,0xee,0xe8,0x1a,0x02,0xb0,0x08,0xe8,
0xc3,0x02,0xe8,0x82,0x02,0xe8,0x7f,0x02,0xe8,0x02,0x00,0x61,0xc3,0x50,0x1e,0x6a,
0x40,0x1f,0x8a,0x26,0x8b,0x00,0x1f,0xb0,0x03,0xe8,0xa9,0x02,0xb0,0xbf,0x80,0xe4,
0xc0,0x74,0x09,0xb0,0xaf,0x80,0xfc,0xc0,0x74,0x02,0xb0,0xdf,0xe8,0x96,0x02,0xb0,
0x02,0xe8,0x91,0x02,0x58,0xc3,0x60,0x1e,0xb0,0xff,0x72,0x0a,0x6a,0x00,0x1f,0xc5,
0x1e,0x78,0x00,0x8a,0x47,0x02,0x6a,0x40,0x1f,0xa2,0x40,0x00,0x1f,0x61,0xc3,0x60,
0xe8,0x87,0x00,0xe8,0xb7,0xff,0xb4,0x01,0x8a,0x0e,0x0c,0x00,0xd2,0xe4,0x1e,0x6a,
0x40,0x1f,0x84,0x26,0x3e,0x00,0x1f,0x75,0x05,0xe8,0xa6,0x00,0x72,0x69,0xbb,0x94,
0x00,0x02,0x1e,0x0c,0x00,0xa0,0x11,0x00,0x1e,0x6a,0x40,0x1f,0x08,0x26,0x3e,0x00,
0x8a,0x26,0x41,0x00,0x3a,0x07,0x88,0x07,0x1f,0x75,0x05,0x80,0xfc,0x40,0x75,0x44,
0xb0,0x0f,0xe8,0x30,0x02,0x72,0x40,0xa0,0x12,0x00,0xc0,0xe0,0x02,0x0a,0x06,0x0c,
0x00,0xe8,0x21,0x02,0xa0,0x11,0x00,0xe8,0x1b,0x02,0xe8,0x6a,0x01,0x72,0x28,0xb0,
0x08,0xe8,0x11,0x02,0x72,0x21,0xe8,0xce,0x01,0x72,0x1c,0x8a,0xe0,0xe8,0xc7,0x01,
0xf6,0xc4,0xc0,0x75,0x12,0xb0,0x0f,0x80,0x3e,0x27,0x00,0x4a,0x74,0x02,0xb0,0x01,
0x98,0xe8,0x38,0x02,0x61,0xf8,0xc3,0x61,0xf9,0xc3,0x60,0xe8,0x4a,0xf9,0x8b,0x44,
0x06,0x74,0x02,0x8a,0xc4,0x1e,0x6a,0x40,0x1f,0x8a,0x26,0x8b,0x00,0xc0,0xec,0x06,
0x3a,0xc4,0x74,0x10,0xba,0xf7,0x03,0xee,0xc0,0xe0,0x06,0x80,0x26,0x8b,0x00,0x3f,
0x08,0x06,0x8b,0x00,0x1f,0xbf,0x1f,0x00,0xb9,0x08,0x00,0x88,0x2d,0x47,0xe2,0xfb,
0x61,0xc3,0x60,0xbb,0x94,0x00,0x02,0x1e,0x0c,0x00,0x1e,0x6a,0x40,0x1f,0x88,0x3f,
0x1f,0xb9,0x02,0x00,0xb0,0x07,0xe8,0x9c,0x01,0x72,0x35,0xa0,0x12,0x00,0xc0,0xe0,
0x02,0x0a,0x06,0x0c,0x00,0xe8,0x8d,0x01,0x72,0x26,0xe8,0xda,0x00,0x72,0x21,0xb0,
0x08,0xe8,0x81,0x01,0x72,0x1a,0xe8,0x3e,0x01,0x72,0x15,0x8a,0xe0,0xe8,0x37,0x01,
0x80,0xf4,0x20,0xf6,0xc4,0xf0,0x75,0x08,0xb8,0x01,0x00,0xe8,0xae,0x01,0xeb,0x03,
0xe2,0xc2,0xf9,0x61,0xc3,0x50,0x53,0x51,0x52,0x8a,0x0e,0x18,0x00,0xb5,0x00,0xf9,
0xd2,0xd5,0xb1,0x00,0xa0,0x15,0x00,0x2a,0x06,0x14,0x00,0x40,0x98,0xf7,0xe1,0x8b,
0xd0,0x8b,0xc8,0x49,0x8c,0xc0,0xe8,0x72,0x00,0x72,0x6a,0xa0,0x27,0x00,0xe8,0xb7,
0x00,0x3c,0x4a,0xb0,0xc5,0x74,0x02,0xb0,0xe6,0xe8,0x29,0x01,0x72,0x57,0xa0,0x12,
0x00,0xc0,0xe0,0x02,0x0a,0x06,0x0c,0x00,0xe8,0x1a,0x01,0xa0,0x11,0x00,0xe8,0x14,
0x01,0xa0,0x12,0x00,0xe8,0x0e,0x01,0xa0,0x14,0x00,0xe8,0x08,0x01,0xa0,0x18,0x00,
0xe8,0x02,0x01,0xa0,0x15,0x00,0xe8,0xfc,0x00,0x8a,0x44,0x08,0xe8,0xf6,0x00,0xb0,
0x80,0xe8,0xf1,0x00,0xe8,0x40,0x00,0x9c,0xbb,0x20,0x00,0xb9,0x07,0x00,0xe8,0xa6,
0x00,0x88,0x07,0x43,0xe2,0xf8,0x9d,0x72,0x0c,0xf6,0x06,0x20,0x00,0xc0,0x75,0x05,
0x03,0xfa,0xf8,0xeb,0x01,0xf9,0x5a,0x59,0x5b,0x58,0xc3,0x52,0xbb,0x10,0x00,0xf7,
0xe3,0x03,0xc7,0x83,0xd2,0x00,0x8b,0xd8,0x8a,0xe2,0x8b,0xd1,0x03,0xd3,0x73,0x05,
0xc6,0x06,0x1f,0x00,0x09,0x5a,0xc3,0xfb,0x60,0x1e,0x6a,0x40,0x1f,0xb8,0x01,0x90,
0xf8,0xcd,0x15,0xba,0x80,0x02,0xbb,0x3e,0x00,0x72,0x0f,0x33,0xc9,0x84,0x17,0x75,
0x0f,0xe8,0xf6,0x00,0xe2,0xf7,0xfe,0xce,0x75,0xf1,0x2e,0x08,0x16,0x1f,0x00,0xf9,
0x9c,0x80,0x27,0x7f,0x9d,0x1f,0x61,0xc3,0x50,0xfa,0xe6,0x0b,0xb0,0x00,0xeb,0x00,
0xeb,0x00,0xe6,0x0c,0x8a,0xc3,0xeb,0x00,0xeb,0x00,0xe6,0x04,0x8a,0xc7,0xeb,0x00,
0xeb,0x00,0xe6,0x04,0xeb,0x00,0xeb,0x00,0x8a,0xc4,0xe6,0x81,0x8a,0xc1,0xeb,0x00,
0xeb,0x00,0xe6,0x05,0x8a,0xc5,0xeb,0x00,0xeb,0x00,0xe6,0x05,0xfb,0xb0,0x02,0xeb,
0x00,0xeb,0x00,0xe6,0x0a,0x58,0xc3,0x51,0x52,0x50,0xe8,0x72,0x00,0xba,0xf4,0x03,
0xb9,0x85,0x00,0xeb,0x00,0xeb,0x00,0xec,0x24,0xc0,0x3c,0xc0,0x74,0x1c,0xeb,0x00,
0xeb,0x00,0xe4,0x61,0x24,0x10,0x3a,0xc4,0x74,0xe9,0x8a,0xe0,0xe2,0xe5,0x58,0x5a,
0x59,0x80,0x0e,0x1f,0x00,0x80,0xb0,0x00,0xf9,0xc3,0x58,0x42,0xeb,0x00,0xeb,0x00,
0xec,0x5a,0x59,0xf8,0xc3,0x51,0x52,0x50,0xe8,0x34,0x00,0xba,0xf4,0x03,0xb9,0x85,
0x00,0xeb,0x00,0xeb,0x00,0xec,0xa8,0x80,0x75,0x1a,0xeb,0x00,0xeb,0x00,0xe4,0x61,
0x24,0x10,0x3a,0xc4,0x74,0xeb,0x8a,0xe0,0xe2,0xe7,0x58,0x5a,0x59,0x80,0x0e,0x1f,
0x00,0x80,0xf9,0xc3,0x42,0x58,0xeb,0x00,0xeb,0x00,0xee,0x5a,0x59,0xf8,0xc3,0x50,
0x51,0xb9,0x04,0x00,0xe8,0x23,0x00,0xe2,0xfb,0x59,0x58,0xc3,0x9c,0x60,0xba,0x4a,
0x42,0xf7,0xe2,0x8a,0xcc,0x8a,0xea,0x8a,0xd6,0xb6,0x00,0xe8,0x0c,0x00,0xe2,0xfb,
0x23,0xd2,0x74,0x03,0x4a,0xeb,0xf4,0x61,0x9d,0xc3,0xeb,0x00,0xeb,0x00,0xe4,0x61,
0x24,0x10,0x3a,0xc4,0x74,0xf4,0x8a,0xe0,0xc3,0x1e,0x16,0x1f,0x26,0xa2,0x2b,0x00,
0x26,0x88,0x26,0x43,0x00,0xbf,0xfc,0x09,0xbe,0x4c,0x00,0xfc,0xfa,0xa5,0xa5,0xc7,
0x44,0xfc,0x5b,0x00,0x8c,0x44,0xfe,0xfb,0x1f,0xcb,0x00,0x00,0xd9,0x09,0x55,0xaa
};
#endif

char program_2m_magic[] = {
0x2b,0x00,0x43,0x00,0x32,0x30,0x32,0x4d,0x2d,0x53,0x54,0x56,0x00,0x00,0x00,0x00
};

do_2m_write()
{
   int i;
   char * mbr;

   if( read_sector(bs_offset+1, buffer+512) != 0 )
      exit(1);

   if( memcmp(buffer+512, program_2m_magic, 16) == 0 )
   {
      /* Seems to be properly formatted already */

      write_sector(bs_offset, buffer);
      return;
   }
#ifdef HAS_2M20
   else if( disk_trck != 82 || disk_sect != 22 )
   {
      fprintf(stderr, "To be bootable a 2M disk must be 22 sectors 82 tracks or formatted with DOS 2m.\n");
      if( !force ) exit(1);
      fprintf(stderr, "But I'll try it\n");
   }
   write_sector(bs_offset, buffer);

   /* This needs to be altered to allow for the disk format description to
      be copied from the old boot sector */

   if( disk_sect == 23 ) mbr = boot_sector_2m_23_82;
   else                  mbr = boot_sector_2m_22_82;

   for(i=0; i<sysboot_dosfs_stat; i++)
      buffer[i] = mbr[i];
   for(i=sysboot_codestart; i<512; i++)
      buffer[i] = mbr[i];

   write_sector(0, buffer);

   for(i=0; i<sizeof(program_2m_vsn_20); i+=512)
   {
      write_sector(bs_offset+i/512+1, program_2m_vsn_20+i);
   }
#else
   fprintf(stderr, "To be bootable a 2M disk must be formatted with the DOS 2m driver.\n");
   exit(1);
#endif
}

Generated by  Doxygen 1.6.0   Back to index