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