home *** CD-ROM | disk | FTP | other *** search
/ No Fragments Archive 12: Textmags & Docs / nf_archive_12.iso / MAGS / SOURCES / ATARI_SRC.ZIP / atari source / HDX_BACK / HDX402 / HDX.C < prev    next >
Encoding:
C/C++ Source or Header  |  2001-02-09  |  21.6 KB  |  904 lines

  1. /* hdx.c */
  2.  
  3. /*
  4.  * Atari Hard Disk Installation Utility
  5.  * Copyright 1988 Atari Corp.
  6.  *
  7.  * Associated files
  8.  *    hdx.rsc        resource file
  9.  *    wincap        hard disk database (text file)
  10.  *
  11.  *    hdx.h        object tree definitions
  12.  *    defs.h        constant definitions
  13.  *    part.h        ST structure definitions
  14.  *    ipart.h        IBM structure definitions
  15.  *
  16.  *    hdx.c        top level, user interface (this file)
  17.  *    epart.c        edit partition sizes
  18.  *    fmt.c        disk formatting
  19.  *    part.c        partition reading/writing
  20.  *    sect.c        sector reading, writing, zeroing
  21.  *    string.c    string functions (matching, concat, ...)
  22.  *    assist.c    markbad(), zero()
  23.  *    wincap.c    hard disk parameter / partition size database
  24.  *    st.c        random ST functions (delay, reboot, ...)
  25.  *
  26.  *----
  27.  * 11-May-1988    ml.    Cleaned up the memory management in the program
  28.  *            (ie. for all files).  Memory chunks which are for
  29.  *            sure will be < 32k is allocated using malloc(),
  30.  *            whereas chunks >= 32k is allocated using Malloc().
  31.  *            When using malloc(), you will get the 'Stack Over-
  32.  *            flow message if you are in Supervisor mode and 
  33.  *            you have your own supervisor stack.  To get around
  34.  *            this, have to use mymalloc() (in mymalloc.s).
  35.  * 15-Mar-1988    ml.    Changed interface to Markbad.
  36.  * 11-Jan-1988    ml.    Modified dialogue boxes.
  37.  * 07-Dec-1987    ml.    Started to add in concept of Bad Sector List.
  38.  * ??-Oct-1987  ml.    Partition and Disk type menu now has 15 entries 
  39.  *            instead of 16.
  40.  * 30-Sep-1987    ml.    Inherited 'this' from Landon Dyer.
  41.  * 24-Mar-1986 lmd    Released to software test.
  42.  * 15-Mar-1986 lmd    Hacked up from earlier version by Jim Tittsler.
  43.  * 8-Nov-1988  jye. change and add some codes so that can be used for extended
  44.  *                    and big partition.
  45.  * 13-Jun-1989 jye. Change and add some codes so that HDX can be deal with
  46.  *                    acsi and scsi drives.
  47.  * 22-Jan-1990 jye. Change the HDX so that we don't have to put a informations
  48.  *                    of a drive into the Wincap file.
  49.  * 13-Mar-1990 jye. change the HDX to a genetic one so that the user don't
  50.  *                    need know what kind of drive.
  51.  * 20-Jul-1990 jye. change the interface about the unit select. In the new 
  52.  *                    interface, user tells the type of drive is acsi or scsi,
  53.  *                    then selects unit.
  54.  * 01-Aug-1990 jye. Change hard disk size request from mdsence to readcap.
  55.  * 25-Jul-1991 jye. Change the Hdx so that can be used for IDE-AT drive.
  56.  *
  57.  */
  58.  
  59. #include "obdefs.h"
  60. #include "gemdefs.h"
  61. #include "osbind.h"
  62. #include "mydefs.h"
  63. #include "part.h"
  64. #include "bsl.h"
  65. #include "hdx.h"
  66. #include "bookfmt.h"
  67. #include "addr.h"
  68. #include "myerror.h"
  69.  
  70. #define MFM 17
  71.  
  72. extern char sbuf[];
  73. extern long gbslsiz();
  74. extern long bslsiz;
  75. extern BYTE *bsl;
  76. extern int yesscan;
  77. extern long disksiz;
  78. extern long ratio;
  79.  
  80. /* Globals */
  81. int rebootp = 0;    /* 1: must reboot (not return to desktop) */
  82. int tformat;            /* TRUE: just formatted disk */
  83. char sbuf[512];        /* error message buffer */
  84. long extsiz;        /* the size of extened partition */
  85. long ostack;                /* old stack pointer */
  86. long bps;            /* bytes per sector */
  87. int npart;            /* number of partition */
  88. int ext;            /* the index of extended partition */
  89. int extend;            /* the index of end extended partition */
  90. int needscan;        /* TRUE: if info in the LOGMAP update */
  91. int athead;            /* the # of data heads on the AT drive */
  92. int atcyl;            /* the # of cylinders on the AT drive */
  93. int atspt;            /* the # of sectors per track on the AT drive */
  94.  
  95. /*  Logical-to-dev+partition mapping table. */
  96. extern char cachexst;        /* 0: no cache. 1: with cache */
  97.  
  98. /* AES (windows and messages) related variables */
  99. int gl_hchar;        /* height of system font (pixels) */
  100. int gl_wchar;        /* width of system font (pixels) */
  101. int gl_wbox;        /* width of box able to hold system font */
  102. int gl_hbox;        /* height of box able to hold system font */
  103.  
  104. int phys_handle;    /* physical workstation handle */
  105. int handle;        /* virtual workstation handle */
  106. int wi_handle;        /* window handle */
  107.  
  108. int formw, formh, sx, sy, lx, ly;    /* dialogue box dimensions */
  109. int xdesk, ydesk, hdesk, wdesk;        /* window X, Y, width, height */
  110. int xwork, ywork, hwork, wwork;        /* desktop and work areas */
  111.  
  112. int msgbuff[8];        /* event message buffer */
  113. int keycode;        /* keycode returned by event-keyboard */
  114. int mx, my;        /* mouse x and y pos. */
  115. int butdown;        /* button state tested for, UP/DOWN */
  116. int ret;        /* dummy return variable */
  117. int pnf;        /* 1: partition or format; 0: zero or markbad */
  118. int hidden;        /* current state of cursor */
  119. int contrl[12];
  120. int intin[128];
  121. int ptsin[128];
  122. int intout[128];
  123. int ptsout[128];    /* storage wasted for idiotic bindings */
  124. int work_in[11];    /* Input to GSX parameter array */
  125. int work_out[57];    /* Output from GSX parameter array */
  126. int pxyarray[10];    /* input point array */
  127.  
  128. /*
  129.  * Top level;
  130.  * we get control from the desktop.
  131.  */
  132. main()
  133. {
  134.     pnf = 0;        /* set the flag to it isn't partition yet */
  135.     appl_init();
  136.     phys_handle=graf_handle(&gl_wchar, &gl_hchar, &gl_wbox, &gl_hbox);
  137.     wind_get(0, WF_WORKXYWH, &xdesk, &ydesk, &wdesk, &hdesk);
  138.     open_vwork();
  139.     wi_handle=wind_create(0x0040&0x0080, xdesk, ydesk, wdesk, hdesk);
  140.  
  141.     hidden = FALSE;
  142.     butdown = TRUE;
  143.  
  144.     /* doing a checking see if the cache in the system */
  145.     cachexst = (char) chkcache();
  146.  
  147.     rsrc_load(RESOURCEFILE);
  148.     /* Get all addresses of dialogues from resource file */
  149.     getalladdr();
  150.  
  151.     needscan = TRUE;
  152.  
  153.        if (domulti() != 11)
  154.         reboot();
  155.  
  156.     wind_delete(wi_handle);
  157.     v_clsvwk(handle);
  158.     appl_exit();
  159. }
  160.  
  161.  
  162. /*
  163.  * Get a single event, process it, and return.
  164.  *
  165.  */
  166. domulti(){
  167.     int event;
  168.     int skipit = 11;
  169.     
  170.             wind_update(TRUE);
  171.             BEE_MOUSE;
  172.             if (rescan(0,0) != OK) {
  173.                 errs("[3][|", CANTFMT, "][ EXIT ]");
  174.                 ret = skipit;
  175.                 goto fnshfmt;
  176.             }
  177.             tformat = TRUE;
  178.             needscan = FALSE;
  179.             if ((ret = dodiform()) != OK)    {
  180.                 if (ret == ERROR)
  181.                     errs("[3][|", CANTFMT, "][ EXIT ]");
  182.                 else
  183.                     ret = skipit;
  184.             } else {
  185.                 errs("[0][| |", OKFMT, "][ EXIT ]");
  186.             }
  187.     fnshfmt:
  188.             tformat = FALSE;
  189.                wind_update(FALSE);
  190.             return(ret);
  191. }
  192.  
  193.  
  194.  
  195. /*
  196.  * Handle [FORMAT] item.
  197.  *
  198.  */
  199. dodiform()
  200. {
  201.   extern char bootstop;
  202.   extern char bootend;
  203.   int dev, v, w, i, ret;
  204.   int modesel;            /* flag for mode select */
  205.   long cnt, hdsiz;
  206.   char *s, *d, *wgetstr();
  207.   char buf[10], bs[512]; 
  208.   char *seldev =  "IDE  unit 0";
  209.   long nbad;
  210.   extern long gbslsiz(), nument(), dsmarkbad();
  211.   long pattern, temp;
  212.   long longrandom();
  213.   int set, bsiz;
  214.   
  215.   /*
  216.    * Throw up generic formatting/partition warning,
  217.    * then get physical dev they want to clobber.
  218.    */
  219.   yesscan = 0;
  220.   fwarning[FWARNCN].ob_state = NORMAL;
  221.   fwarning[FWARNOK].ob_state = NORMAL;
  222.   if (execform(fwarning) != FWARNOK) return 10;
  223.   dev = 0;
  224.   pattern = longrandom();  /* can't find pattern from wincap, make one */
  225.  
  226.   /* For REAL !! */  
  227.   dsplymsg(fmtmsg);
  228.   bsl = 0L;
  229.   
  230.   /* Get size of Bad Sector List */
  231.   if ((bslsiz = gbslsiz(dev)) > 0L) {
  232.       /* Allocate memory for existing BSL */
  233.       if ((bsl = (BYTE *)mymalloc((int)bslsiz*512)) <= 0) {
  234.           ret = ERROR;
  235.           goto formend;
  236.       }
  237.       
  238.       /* Read in BSL */
  239.       if ((ret = rdbsl(dev)) != OK) {
  240.           /* Create a new BSL if current one is unusable */
  241.           if (creabsl(dev, NEW, 0L) != OK) {
  242.               ret = ERROR;
  243.               goto formend;
  244.           }
  245.       } else {
  246.             /* Remove USER BSL */
  247.             if (creabsl(dev, EXPAND, nument(VENDOR)) != OK) {
  248.                 ret = ERROR;
  249.                 goto formend;
  250.             }
  251.       }
  252.   } else if (bslsiz == 0L || bslsiz == ERROR) {    /* no bsl or read error */
  253.       if (creabsl(dev, NEW, 0L) != OK) {
  254.           ret = ERROR;
  255.           goto formend;
  256.       }
  257.   } else {    /* bslsiz == MDMERR; medium changed error */
  258.       ret = ERROR;
  259.       goto formend;
  260.   }
  261.   
  262.   /*
  263.    * In supervisor mode
  264.    * set disk format parameters
  265.    * and format the disk.
  266.    */
  267.   ostack = Super(NULL);
  268.   if ((ret = fmtunt(dev)) != OK)    {
  269.       ret = ERROR;
  270.   } else {
  271.       hdsiz = athead*atcyl*atspt;
  272.     disksiz = hdsiz;
  273.   }
  274.   delay();
  275.   Super(ostack);
  276. formend:
  277.   erasemsg();    /* Erase formatting box */
  278.   if (ret < 0) {
  279.       if (bsl > 0) free(bsl);
  280.       return ERROR;
  281.   }
  282.   
  283.   /*------------------------------------------*
  284.    * Markbad the device destructively.          *
  285.    * Bad Sectors found are added to the BSL.  *
  286.    * Write BSL to device.              *
  287.    *------------------------------------------*/
  288.   if ((nbad = dsmarkbad(dev, hdsiz, 1, pattern)) < 0) {
  289.       free(bsl);
  290.       return ERROR;
  291.   }
  292.   if (wrbsl(dev) != OK) {
  293.       free(bsl);
  294.       return ERROR;
  295.   }
  296.   free(bsl);
  297.  
  298.     
  299.   /*
  300.    * Install boot-stopper in sector image;
  301.    * write root sector to device.
  302.    * 6-13-88  Setting of soft format parameters in root sector sets
  303.    *        the hard disk size only.
  304.    */
  305.   fillbuf(bs, 512L, 0L);    /* create new root sector */
  306.   sbslparm(bs);            /* set BSL parameters */
  307.   ((RSECT *)(bs + 0x200 - sizeof(RSECT)))->hd_siz =disksiz;
  308.   for (d = bs, s = &bootstop, cnt = (long)(&bootend - &bootstop); --cnt;)
  309.     *d++ = *s++;
  310.   Protobt(bs, -1L, -1, 1);    /* make root sector executable */
  311.   
  312.   if ((ret = putroot(dev, bs, (SECTOR)0)) != OK) {
  313.       return ERROR;
  314.   }
  315.  
  316.   if (dodipart(dev, disksiz) != OK)
  317.       return ERROR;
  318.  
  319.   dsplymsg(instlmsg);
  320.   if (Pexec(0, ".\\bookinst.prg\0", NULL, NULL) != OK)
  321.       return ERROR;
  322.   erasemsg();
  323.   return OK;
  324. }
  325.  
  326.  
  327.  
  328.  
  329. /*
  330.  * Handle [PARTITION] item;
  331.  * if `xdev' is -1, throw up dialog boxes;
  332.  * if `xdev' >= 0, just partition the dev,
  333.  * using `pnam' as the partition type, 
  334.  * and `pr_id' to search for the type.
  335.  *
  336.  */
  337. dodipart(xdev, hsize)
  338. int xdev;
  339. long hsize;
  340. {
  341.     int dev, i, ret =OK, fine;
  342.     int choice;
  343.     char *s;
  344.     char bs[512];
  345.     PART *pinfo;
  346.     int tem1, tem2;
  347.     long disksiz;
  348.  
  349.     npart = 4;
  350.     ext = NO_EXT;    /* set the extended partition flag to not exists */
  351.     dev = xdev;
  352.     if ((pinfo = (PART *)Malloc((long)sizeof(PART)*npart)) <= 0)    {
  353.         if (pinfo > 0)    Mfree(pinfo);
  354.         return ERROR;
  355.     }
  356.     inipart(pinfo, npart);
  357.     npart = 0;
  358.     setpart(pinfo, hsize);
  359.  
  360.     /* For REAL!! */
  361.     dsplymsg(partmsg);
  362.     bsl = 0L;
  363.     
  364.     /* Get size of BSL */
  365.     if ((bslsiz = gbslsiz(dev)) > 0L) {
  366.         /* Allocate memory for existing BSL */
  367.         if ((bsl = (BYTE *)mymalloc((int)bslsiz*512)) <= 0) {
  368.             ret = ERROR;
  369.             goto partend;
  370.         }
  371.             
  372.         /* Read in BSL */
  373.         if ((ret = rdbsl(dev)) != OK) {
  374.             ret = ERROR;
  375.             goto partend;
  376.         }
  377.     } else if (bslsiz == 0) {
  378.         ret = ERROR;
  379.         goto partend;
  380.     } else if (bslsiz == ERROR) {
  381.         ret = ERROR;
  382.         goto partend;
  383.     } else {
  384.         ret = ERROR;
  385.         goto partend;
  386.     }
  387.  
  388.     
  389.     /* Lay out partition headers */
  390.     if (spheader(dev, &pinfo[0]) != OK) {
  391.         ret = ERROR;
  392.         goto partend;
  393.     }
  394.     
  395.     if (wrbsl(dev) != OK) {        /* write BSL */
  396.         ret = ERROR;
  397.         goto partend;
  398.     }
  399.  
  400.     /* check and change the structure's id after 'spheader()' */
  401.     changeid(pinfo);
  402.  
  403.     /* Shove partition parms into root sector */
  404.     if ((ret = getroot(dev, bs, (SECTOR)0)) != 0)    {
  405.         ret = ERROR;
  406.         goto partend;
  407.     }
  408.  
  409.     if ((ret = stlayroot(bs, dev, pinfo)) != OK)    {
  410.         goto partend;
  411.     }
  412.     tem1 = npart;            /* save the number of partitions */
  413.     tem2 = ext;                /* save the index of extended partition */
  414.     if (rescan(1,0)) {        /* has to be here because map changed    */
  415.         ret = ERROR;        /* after partitions are moved around,    */
  416.         goto partend;        /* report medium change error.        */
  417.     }
  418.     npart = tem1;
  419.     ext = tem2;
  420.     /* Partition the device with parameters given in pinfo */
  421.     ret = stlaybs(dev, &pinfo[0]);
  422.         
  423.     rebootp = 1;
  424.     pnf = 1;        /* set the flag to just doing the partition */
  425. partend:
  426.     if (bsl > 0) free(bsl);
  427.     inipart(pinfo, npart);
  428.     if (pinfo > 0)    Mfree(pinfo);
  429.     erasemsg();
  430.     return (ret);
  431. }
  432.  
  433.  
  434. /*
  435.  * get root sector informations and write them into that sector 
  436.  */
  437.  
  438. stlayroot(bs, dev, part)
  439. char *bs;
  440. int dev;
  441. PART *part;
  442. {
  443.     int i;
  444.     UWORD sum = 0x1234;
  445.     long cnt, disksiz, prvst;
  446.     char *d, *s;
  447.     extern char bootstop;
  448.     extern char bootend;
  449.  
  450.     /* do the prime partition */
  451.     spart(bs, part, 0, &prvst);    /* set ST partition parameters */
  452.     sbslparm(bs);                /* set bsl parameters */
  453.     Protobt(bs, -1L, -1, 1);        /* make root sector executable */
  454.     if ((ret = putroot(dev, bs, (SECTOR)0)) != OK) {
  455.         return(ERROR);
  456.     }
  457.     if (ext == NO_EXT)    return OK;        /* no extended partition */
  458.     /* do the extended partitions */
  459.     extsiz = part[ext].p_siz;
  460.     for (i = 4; i < npart; i++)    {
  461.         if (!(part[i].p_flg & P_EXISTS))    {     /* skip if not exists */
  462.             return OK;
  463.         }
  464.         spart(bs, part, i, &prvst);    /* set IBM partition parameters */
  465.         if (putroot(dev, bs, part[i].p_st) != OK) {
  466.             return(ERROR);
  467.         }
  468.     }
  469.     return OK;
  470. }
  471.  
  472.  
  473.  
  474.  
  475. /*
  476.  * Put information into the root structure
  477.  */
  478.  
  479. spart(image, pinfo, pnm, prvst)
  480.  
  481. char *image;            /* root sector buffer */
  482. register PART *pinfo;    /* partition information */
  483. int pnm;                /* partition number */
  484. long *prvst;            /* The previous partition start sector */
  485.  
  486. {
  487.     PART *rpart;
  488.     long numcyl;
  489.     int i, j;
  490.  
  491.     if (pnm)     {
  492.         fillbuf(image, 512L, 0L);
  493.     }
  494.     rpart = &((RSECT *)(image + 0x200 - sizeof(RSECT)))->hd_p[0];
  495.     if (pnm < 4)    {
  496.         for (i = 0; i < NPARTS; i++, rpart++)    {
  497.             if (pinfo->p_flg & P_EXISTS)    {
  498.                 rpart->p_flg = P_EXISTS;
  499.                 for (j = 0; j < 3; j++)
  500.                     rpart->p_id[j] = pinfo->p_id[j];
  501.                 rpart->p_st = pinfo->p_st;
  502.                 rpart->p_siz = pinfo->p_siz;
  503.             } else {
  504.                 rpart->p_flg = 0;
  505.                 for (j = 0; j < 3; j++)
  506.                     rpart->p_id[j] = 0;
  507.                 rpart->p_st = 0L;
  508.                 rpart->p_siz = 0L;
  509.             }
  510.             pinfo++;
  511.         }
  512.  
  513.     } else {    /* pnm => 4 */
  514.         rpart->p_flg = pinfo[pnm].p_flg;
  515.         for (j = 0; j < 3; j++)
  516.             rpart->p_id[j] = pinfo[pnm].p_id[j];
  517.         rpart->p_st = ROOTSECT;
  518.         rpart->p_siz = pinfo[pnm].p_siz - ROOTSECT;
  519.         rpart++;
  520.         if (((pnm + 1) != npart) && (pinfo[pnm+1].p_flg & P_EXISTS)) { 
  521.             /* need extened partition */
  522.             rpart->p_flg = P_EXISTS;
  523.             rpart->p_id[0] = 'X';
  524.             rpart->p_id[1] = 'G';
  525.             rpart->p_id[2] = 'M';
  526.             rpart->p_siz = pinfo[pnm+1].p_siz;
  527.             rpart->p_st = (pnm == 4) ? (pinfo[4].p_siz) :
  528.                                     (pinfo[pnm].p_siz + *prvst);
  529.             *prvst = rpart->p_st;
  530.         }
  531.  
  532.     }
  533. }
  534.  
  535.  
  536.  
  537. /*
  538.  * Setup partitions on the disk;
  539.  * write boot sectors and zero FATs and root directories.
  540.  *
  541.  */
  542. stlaybs(physdev, pinfo)
  543. int physdev;
  544. register PART *pinfo;
  545. {
  546.     int i, ldev, ret;
  547.     int kindfat;
  548.     SECTOR data, nsect;
  549.     char *devno="X";
  550.     long ndirs;
  551.     UWORD fatsiz;
  552.     BOOT *bs;
  553.     long serialno;
  554.     extern long longrandom();
  555.     extern long cell();
  556.     char *buf;
  557.     long size;
  558.  
  559.     if ((bslsiz = gbslsiz(physdev)) < 0L) {
  560.         return ERROR;
  561.     }
  562.     /* SCAN_BS: pinfo is for scan() and laybs() use */
  563.     if (ext != NO_EXT)    sortpart(pinfo, SCAN_BS);    
  564.  
  565.     for (i = 0; i < npart; ++i, ++pinfo) {
  566.         
  567.         /* don't care if partition does not exist */
  568.         if (!(pinfo->p_flg & P_EXISTS)) {
  569.             return OK;
  570.         }
  571.  
  572.  
  573.     /* estimat the bps */
  574.     /* MAXSECT = 16MB - 8 */
  575.     bps = cell((pinfo->p_siz-7)*BPS, (long)MAXSECT);
  576.  
  577.     /* the real bps */
  578.     bps = BPS * n2power((UWORD)cell(bps, (long)BPS));
  579.     ratio = bps / BPS;
  580.     nsect = pinfo->p_siz / ratio;
  581.  
  582.     size = (long)BPS * ratio;
  583.     if ((buf = (char *)Malloc(size)) <= 0)    {
  584.         if (buf > 0) Mfree((long)buf);
  585.         return ERROR;
  586.     }
  587.  
  588.     /*
  589.      * Install entries in boot sector image;
  590.      * force sector checksum to zero (non-executable);
  591.      * write boot sector to media.
  592.      *
  593.       *    512 bytes/sector
  594.      *    2 or 4 sectors/cluster (partition > 16Mb has 4 spc)
  595.      *    1 reserved sector (for boot)
  596.      *    2 FATs
  597.      *    ... dir slots
  598.      *    ... # sectors
  599.      *    F8 means media is a hard disk
  600.      *    ... FAT size
  601.      *
  602.      */
  603.      
  604.     /* Make a clean boot sector */
  605.     fillbuf(buf, bps, 0L);
  606.     bs = (BOOT *)buf;
  607.         
  608.  
  609.     /* bytes per sector */
  610.     iw((UWORD *)&bs->b_bps[0], (UWORD)bps);
  611.     
  612.     /* sectors per cluster */
  613.     bs->b_spc = SPC;
  614.         
  615.     /* number of reserved sectors */
  616.     iw((UWORD *)&bs->b_res[0], (UWORD)1);
  617.     
  618.     /* number of FATs */
  619.     bs->b_nfats = 2;
  620.     
  621.  
  622.     /*
  623.      * Compute root directory size
  624.      * 256 entries, plus fudge on devs > 10Mb
  625.      */
  626.     if (pinfo->p_siz < 0x5000L) ndirs = NUMEN;
  627.     else ndirs = nsect / 80;    /* 1 dir entry per 80 sectors */
  628.     /* round to nearest sector */
  629.     ndirs = (ndirs + ((UWORD)bps/BPDIR - 1)) & ~((UWORD)bps/BPDIR - 1);    
  630.     iw((UWORD *)&bs->b_ndirs[0], (UWORD)ndirs);
  631.     
  632.     /* number of sectors on media (partition) */
  633.     iw((UWORD *)&bs->b_nsects[0], (UWORD)nsect);
  634.  
  635.     /* media descriptor */
  636.     bs->b_media = 0xf8;
  637.  
  638.     /*--------------------------------------------------------------*
  639.      * Compute FAT size                        *
  640.      *                                *
  641.      * Num entries to map the entire partition            *
  642.      *    = partition's size in clusters                *
  643.      *    = partition's size in sectors / spc            *
  644.      *                                *
  645.      * Num entries in FAT                        *
  646.      *    = Num entries to map partition + reserved entries    *
  647.      *    = (partition's size in sectors / spc) + 2        *
  648.      *                                *
  649.      * Num sectors FAT occupies                    *
  650.      *    = Num entries in FAT / Num entries of FAT per sector    *
  651.      *    = Num entries in FAT / (512 / 2)    <16-bit FAT>    *
  652.      *    = ((partition's size in sectors / spc) + 2) / 256 + 1    *
  653.      *                        <+1 to round up>    *
  654.      *--------------------------------------------------------------*/
  655.     fatsiz = ((((nsect / bs->b_spc) + 2) * 2) / bps) + 1;
  656.     iw((UWORD *)&bs->b_spf[0], (UWORD)fatsiz);
  657.  
  658.     /* write the serial number to the bs */ 
  659.     Protobt(bs, 0x01000000, -1, -1);
  660.  
  661.     /*
  662.      * Write partition's boot sector
  663.      */
  664.     forcesum((UWORD *)buf, (UWORD)0);    /* force image checksum */
  665.     if ((ret = wrsects(physdev,(UWORD)ratio,buf,(SECTOR)pinfo->p_st))!= OK) {
  666.         return ERROR;
  667.     }
  668.  
  669.     /*
  670.      * Zero the partition
  671.      */
  672.     if ((ret = zerosect(physdev, (SECTOR)(pinfo->p_st+ratio),
  673.              ((UWORD)((fatsiz*2 + ndirs*BPDIR/bps) * ratio)))) != OK) {
  674.         return ERROR;
  675.     }
  676.              
  677.     /*
  678.      * Make first 2 entries in FATs more IBM-like.
  679.      */
  680.     if ((ret = rdsects(physdev,(UWORD)ratio,buf,
  681.                         (SECTOR)(pinfo->p_st+ratio)))!= 0){
  682.         return ERROR;
  683.     }
  684.     *(UWORD *)&buf[0] = 0xf8ff;
  685.     *(UWORD *)&buf[2] = 0xffff;
  686.     if ((ret = wrsects(physdev,(UWORD)ratio,
  687.                         buf,(SECTOR)(pinfo->p_st+ratio)))!= 0 ||
  688.         (ret = wrsects(physdev,(UWORD)ratio,buf,
  689.                         (SECTOR)(pinfo->p_st+ratio+fatsiz*ratio)))
  690.         != 0) {
  691.         return ERROR;
  692.     }
  693.  
  694.     /*
  695.      * Mark bad sectors recorded in the BSL into the FATs.
  696.      * Calculating parameters:
  697.      *    ldev - from physdev and i.
  698.      *    fat0 - always equals 1.
  699.      *    fatsiz - calculated above.
  700.      *    data - starts after the boot sector, 2 FATs and rootdir.
  701.      */
  702.  
  703.         if (bslsiz > 0) {
  704.             if ((ldev = phys2log(physdev, i)) == ERROR)
  705.                 return ERROR;
  706.             data = (SECTOR)1 + (SECTOR)(fatsiz*2) + (SECTOR)(ndirs*BPDIR/bps);
  707.             bsl2fat(ldev, (SECTOR)ratio, (UWORD)(fatsiz*ratio), 
  708.                                                 data*ratio, MEDIA);
  709.         }
  710.         if (buf > 0) Mfree((long)buf);
  711.     }
  712.     return OK;
  713. }
  714.  
  715.  
  716.  
  717. /*
  718.  * Open virtual workstation.
  719.  *
  720.  */
  721. open_vwork()
  722. {
  723.     int i;
  724.  
  725.     for (i = 0; i < 10;)
  726.     work_in[i++] = 1;
  727.     work_in[10] = 2;
  728.     handle = phys_handle;
  729.     v_opnvwk(work_in, &handle, work_out);
  730. }
  731.  
  732.  
  733. /*
  734.  * Find and redraw all clipping rectangles
  735.  *
  736.  */
  737. do_redraw(xc, yc, wc, hc)
  738. int xc, yc, wc, hc;
  739. {
  740.     GRECT t1, t2;
  741.     int temp[4];
  742.  
  743.     hide_mouse();
  744.     t2.g_x=xc;
  745.     t2.g_y=yc;
  746.     t2.g_w=wc;
  747.     t2.g_h=hc;
  748.     vsf_interior(handle, 1);
  749.     vsf_color(handle, 0);
  750.     wind_get(wi_handle, WF_FIRSTXYWH, &t1.g_x, &t1.g_y, &t1.g_w, &t1.g_h);
  751.     while (t1.g_w && t1.g_h) {
  752.     if (rc_intersect(&t2, &t1)) {
  753.         set_clip(t1.g_x, t1.g_y, t1.g_w, t1.g_h);
  754.         temp[0] = xwork;
  755.         temp[1] = ywork;
  756.         temp[2] = xwork + wwork - 1;
  757.         temp[3] = ywork + hwork - 1;
  758.         v_bar(handle, temp);
  759.     }
  760.     wind_get(wi_handle, WF_NEXTXYWH, &t1.g_x, &t1.g_y, &t1.g_w, &t1.g_h);
  761.     }
  762.  
  763.     show_mouse();
  764. }
  765.  
  766.  
  767. /*
  768.  * Hide the mouse.
  769.  *
  770.  */
  771. hide_mouse()
  772. {
  773.     if (!hidden) {
  774.     graf_mouse(M_OFF, 0L);
  775.     hidden = TRUE;
  776.     }
  777. }
  778.  
  779.  
  780. /*
  781.  * Show the mouse.
  782.  *
  783.  */
  784. show_mouse() 
  785. {
  786.     if (hidden) {
  787.     graf_mouse(M_ON, 0L);
  788.     hidden = FALSE;
  789.     }
  790. }
  791.  
  792.  
  793. /*
  794.  * Set clipping rectangle.
  795.  *
  796.  */
  797. set_clip(x, y, w, h)
  798. int x, y, w, h;
  799. {
  800.     int clip[4];
  801.  
  802.     clip[0] = x;
  803.     clip[1] = y;
  804.     clip[2] = x + w;
  805.     clip[3] = y + h;
  806.     vs_clip(handle, 1, clip);
  807. }
  808.  
  809.  
  810. /*
  811.  * "Execute" form,
  812.  * return thingy that caused the exit.
  813.  *
  814.  */
  815. execform(tree)
  816. OBJECT tree[];
  817. {
  818.     int thingy;
  819.  
  820.     ARROW_MOUSE;
  821.     dsplymsg(tree);
  822.     thingy = form_do(tree, 0);
  823.     erasemsg();
  824.     BEE_MOUSE;
  825.     return thingy;
  826. }
  827.  
  828.  
  829. /*
  830.  *  Display a dialogue box on the screen.
  831.  *    Input:
  832.  *        tree - object tree for dialogue box to be displayed.
  833.  *    Output:
  834.  *        formw, formh, sx, sy, lx, ly - dimensions of box.
  835.  */
  836. dsplymsg(tree)
  837. OBJECT *tree;
  838. {
  839.     form_center(tree,&lx, &ly, &formw, &formh);
  840.  
  841.     /*
  842.     sx = lx + formw / 2;
  843.     sy = ly + formh / 2;
  844.     */
  845.     
  846.     form_dial(1, 0, 0, 0, 0, lx, ly, formw, formh);
  847.     objc_draw(tree, 0, MAX_DEPTH, 0, 0, wdesk, hdesk);
  848. }
  849.  
  850.  
  851. /*
  852.  *  Erase a dialogue box from the screen.
  853.  *    Input:
  854.  *        formw, formh, sx, sy, lx, ly - dimensions of box.
  855.  */
  856. erasemsg()
  857. {
  858.     form_dial(3, 0, 0, 0, 0, lx, ly, formw, formh);
  859. }
  860.  
  861.  
  862.  
  863. /*
  864.  *  Make a long (4-byte) random.
  865.  */ 
  866. long
  867. longrandom()
  868. {
  869.     long pattern;
  870.     
  871.     pattern = Random();
  872.     pattern <<= 16;
  873.     pattern ^= Random();
  874.     
  875.     return (pattern);
  876. }
  877.  
  878. changeid(part)
  879. PART *part;
  880. {
  881.     int i;
  882.     long psiz;
  883.  
  884.     for(i = 0; i < npart; i++)    {
  885.         if (i == ext)    continue;
  886.         if (!(part[i].p_flg & P_EXISTS)) return OK;
  887.         if (i > 3)    {
  888.             psiz = part[i].p_siz - ROOTSECT;
  889.         } else {
  890.             psiz = part[i].p_siz;
  891.         }
  892.         if (psiz < MB16)    {
  893.             part[i].p_id[0] = 'G';
  894.             part[i].p_id[1] = 'E';
  895.             part[i].p_id[2] = 'M';
  896.         } else {
  897.             part[i].p_id[0] = 'B';
  898.             part[i].p_id[1] = 'G';
  899.             part[i].p_id[2] = 'M';
  900.         }
  901.     }
  902. }
  903.  
  904.