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 / HDX500 / HDX.C < prev    next >
Encoding:
C/C++ Source or Header  |  2001-02-09  |  43.6 KB  |  1,823 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.  * 11-Nov-1991 jye. change the hdx so that can got the hard disk size from
  57.  *                    page 0, or 3, or 4, or from the wincap. For the SCSI drive,
  58.  *                    getting the disk size from wincap or readcap.
  59.  */
  60.  
  61. #include "obdefs.h"
  62. #include "gemdefs.h"
  63. #include "osbind.h"
  64. #include "mydefs.h"
  65. #include "part.h"
  66. #include "bsl.h"
  67. #include "hdx.h"
  68. #include "ipart.h"
  69. #include "addr.h"
  70. #include "error.h"
  71.  
  72. #define MFM 17
  73.  
  74. extern char sbuf[];
  75. extern int rebootp;
  76. extern long gbslsiz();
  77. extern long get3bytes();
  78. extern long get4bytes();
  79. extern long bslsiz;
  80. extern BYTE *bsl;
  81. extern int uplim;            /* the number of partitions */
  82. extern long sptrk;
  83. extern long spcyl;
  84. extern int ibmpart;
  85. extern int yesscan;
  86. extern long disksiz;
  87. extern long ratio;
  88. extern int typedev;
  89. extern int typedrv;
  90. extern int prevnpart;
  91. extern int atexst;        /* set for AT drive exist */
  92.  
  93. /* Globals */
  94. int rebootp = 0;    /* 1: must reboot (not return to desktop) */
  95. int tformat;            /* TRUE: just formatted disk */
  96. int running;        /* 1: continue evnt_multi() loop */
  97. char sbuf[512];        /* error message buffer */
  98. long extsiz;        /* the size of extened partition */
  99. long ostack;        /* old stack pointer */
  100. int toibm;            /* the flag of partition to ibm format */
  101. int ibm2st;            /* the flag for IBM partition to ST */
  102. long bps;            /* bytes per sector */
  103. int npart;            /* number of partition */
  104. int ext;            /* the index of extended partition */
  105. int extend;            /* the index of end extended partition */
  106. int showmany;        /* the flag that show the too much device alert box */
  107. char ttscsi;        /* SCSI hard disk drive */
  108. int noacsi;            /* set for no ACSI dirve in the system */
  109. int needscan;        /* TRUE: if info in the LOGMAP update */
  110. int noinfo;            /* 1: no informations in the wincap */
  111. int athead;            /* the # of data heads on the AT drive */
  112. int atcyl;            /* the # of cylinders on the AT drive */
  113. int atspt;            /* the # of sectors per track on the AT drive */
  114.  
  115. /*  Logical-to-dev+partition mapping table. */
  116. extern int nlogdevs;        /* #logical devs found */
  117. extern LOGMAP logmap[];        /* logical dev map */
  118. extern int livedevs[];        /* live physical dev flag */
  119. extern char cachexst;        /* 0: no cache. 1: with cache */
  120.  
  121. /* Partition related variables */
  122. long mxpsiz = MAXPSIZ;
  123.  
  124. /* AES (windows and messages) related variables */
  125. int gl_hchar;        /* height of system font (pixels) */
  126. int gl_wchar;        /* width of system font (pixels) */
  127. int gl_wbox;        /* width of box able to hold system font */
  128. int gl_hbox;        /* height of box able to hold system font */
  129.  
  130. int phys_handle;    /* physical workstation handle */
  131. int handle;        /* virtual workstation handle */
  132. int wi_handle;        /* window handle */
  133.  
  134. int formw, formh, sx, sy, lx, ly;    /* dialogue box dimensions */
  135. int xdesk, ydesk, hdesk, wdesk;        /* window X, Y, width, height */
  136. int xwork, ywork, hwork, wwork;        /* desktop and work areas */
  137.  
  138. int msgbuff[8];        /* event message buffer */
  139. int keycode;        /* keycode returned by event-keyboard */
  140. int mx, my;        /* mouse x and y pos. */
  141. int butdown;        /* button state tested for, UP/DOWN */
  142. int ret;        /* dummy return variable */
  143. int pnf;        /* 1: partition or format; 0: zero or markbad */
  144. int hidden;        /* current state of cursor */
  145. int contrl[12];
  146. int intin[128];
  147. int ptsin[128];
  148. int intout[128];
  149. int ptsout[128];    /* storage wasted for idiotic bindings */
  150. int work_in[11];    /* Input to GSX parameter array */
  151. int work_out[57];    /* Output from GSX parameter array */
  152. int pxyarray[10];    /* input point array */
  153. int blitxst;        /* the flag for check the BLiTTER */
  154.  
  155. /*
  156.  * Top level;
  157.  * we get control from the desktop.
  158.  */
  159. main()
  160. {
  161.     pnf = 0;        /* set the flag to it isn't partition yet */
  162.     appl_init();
  163.     phys_handle=graf_handle(&gl_wchar, &gl_hchar, &gl_wbox, &gl_hbox);
  164.     wind_get(0, WF_WORKXYWH, &xdesk, &ydesk, &wdesk, &hdesk);
  165.     open_vwork();
  166.     wi_handle=wind_create(0x0040&0x0080, xdesk, ydesk, wdesk, hdesk);
  167.  
  168.     hidden = FALSE;
  169.     butdown = TRUE;
  170.  
  171.     /* doing a checking see if the cache in the system */
  172.     cachexst = (char) chkcache();
  173.  
  174.     /* check the existence of the BLiTTER */
  175.     blitxst = chkblit();
  176.  
  177.     if (!rsrc_load(RESOURCEFILE)) {
  178.     errs("[2][|", RESOURCEFILE, "][ EXIT ]");
  179.     goto punt;
  180.     }
  181.  
  182.     
  183.     /* Get all addresses of dialogues from resource file */
  184.     if (getalladdr() != OK) {
  185.     errs("[2][|", RESOURCEFILE, "][ EXIT ]");
  186.     goto punt;
  187.     }
  188.  
  189.  
  190.     /*
  191.      * Get maximum partition size from
  192.      * wincap "@@" entry.
  193.      */
  194.     /*
  195.     if (wgetent("Parameters", "@@") == OK) {
  196.     if (wgetnum("ms", &mxpsiz) != OK)
  197.         mxpsiz = MAXPSIZ;
  198.     } else {
  199.         goto punt;
  200.     }
  201.     */
  202.  
  203.     needscan = TRUE;
  204.  
  205. redomul:
  206.     ARROW_MOUSE;
  207.  
  208.     /* display menu bar */
  209.     menu_bar(menuobj, 1);
  210.  
  211.     running = TRUE;
  212.     while (running) {
  213.         domulti();
  214.     }
  215.  
  216.     /*
  217.      * If nothing has been done to the hard disks
  218.      * then just get out, back to the desktop.
  219.      * Otherwise reboot the system.
  220.      */
  221.     menu_bar(menuobj, 0);        /* erase menu bar */
  222.  
  223. punt:
  224.     /*
  225.      * If we have to reboot,
  226.      * tell the user and then do it.
  227.      *
  228.      */
  229.     if (rebootp) {
  230.         if (form_alert(2, autoboot) == 1)    {
  231.             reboot();
  232.         } else {
  233.             goto redomul;
  234.         }
  235.     }
  236.  
  237.     wind_delete(wi_handle);
  238.     v_clsvwk(handle);
  239.     appl_exit();
  240. }
  241.  
  242.  
  243. /*
  244.  * Get a single event, process it, and return.
  245.  *
  246.  */
  247. domulti(){
  248.     int event;
  249.     
  250.     event = evnt_multi(MU_MESAG,
  251.             1,1,butdown,
  252.             0,0,0,0,0,
  253.             0,0,0,0,0,
  254.             msgbuff,0,0,&mx,&my,&ret,&ret,&keycode,&ret);
  255.  
  256.     if (event & MU_MESAG) {
  257.         wind_update(TRUE);
  258.     switch (msgbuff[0]) {
  259.         case WM_REDRAW:
  260.         do_redraw(msgbuff[4],msgbuff[5],msgbuff[6],msgbuff[7]);
  261.         break;
  262.  
  263.         case MN_SELECTED:
  264.             BEE_MOUSE;
  265.         switch(msgbuff[3]) {
  266.             case MNDISK:
  267.             switch (msgbuff[4]) {
  268.                 case DIFORM:
  269.                     if ((needscan) && (rescan(0,0) == ERROR))    {
  270.                         break;    /* don't report medium changed */
  271.                     }
  272.                     tformat = TRUE;
  273.                     needscan = FALSE;
  274.                     dodiform();
  275.                     tformat = FALSE;
  276.                     break;
  277.                 case DIPART:
  278.                     if ((needscan)&&(rescan(0,0) == ERROR))    {
  279.                         break;    /* don't report medium changed */
  280.                     }
  281.                     needscan = FALSE;
  282.                     dodipart(-1, NULL, NULL);
  283.                     break;
  284.                 case DIZERO:
  285.                     if (pnf)    {
  286.                         err(needboot);
  287.                     } else {
  288.                         if ((needscan)&&(rescan(0,1) == ERROR))    {
  289.                             break;    /* don't report medium changed */
  290.                         }
  291.                         needscan = FALSE;
  292.                         dodizero();
  293.                     }
  294.                     break;
  295.                 case DIMARK:
  296.                     if (pnf)    {
  297.                         err(needboot);
  298.                     } else {
  299.                         if ((needscan)&&(rescan(0,1) == ERROR))    {
  300.                             break;    /* don't report medium changed */
  301.                         }
  302.                         needscan = FALSE;
  303.                         dodimark();
  304.                     }
  305.                     break;
  306.                 case DISHIP:
  307.                     if ((needscan)&&(rescan(0,0) == ERROR))    {
  308.                         break;    /* don't report medium changed */
  309.                     }
  310.                     needscan = FALSE;
  311.                     dodiship();
  312.                     break;
  313.                 default:        break;
  314.             }
  315.             break;
  316.  
  317.             case MNFILE:
  318.             switch (msgbuff[4]) {
  319.                 case FIQUIT:
  320.                 running = 0;
  321.                 break;
  322.  
  323.                 default:
  324.                 break;
  325.             }
  326.             break;
  327.             
  328.             case MNDESK:
  329.             if(msgbuff[4] == DEABOUT) {
  330.                 strcpy(abtdial[ABVERSN].ob_spec, "Version 5.00");
  331.                  abtdial[ABOK].ob_state = NORMAL;
  332.                 execform(abtdial);
  333.             }
  334.             break;        /* "cannot happen" */
  335.         }
  336.  
  337.         menu_tnormal(menuobj, msgbuff[3], 1);    /* back to normal */
  338.             ARROW_MOUSE;
  339.         break;
  340.         
  341.         case WM_NEWTOP:
  342.         case WM_TOPPED:
  343.         wind_set(wi_handle, WF_TOP, 0, 0, 0, 0);
  344.         break;
  345.  
  346.         case WM_CLOSED:
  347.         running = FALSE;
  348.         break;
  349.  
  350.         default:
  351.         break;
  352.     }
  353.     wind_update(FALSE);
  354.     }
  355. }
  356.  
  357.  
  358. /*
  359.  * Default partition name (no "pt" entry).
  360.  */
  361. #define    DEF_PARTNAME    "4-6-10"
  362.  
  363.  
  364. /*
  365.  * Map from button in format dial.
  366.  */
  367. int pfmt[] = {
  368.     PFMT0, PFMT1, PFMT2, PFMT3,
  369.     PFMT4, PFMT5, PFMT6, PFMT7,
  370.     PFMT8, PFMT9, PFMT10, PFMT11,
  371.     PFMT12, PFMT13, PFMT14, PFMT15
  372. };
  373.  
  374.  
  375. /*
  376.  * Handle [FORMAT] item.
  377.  *
  378.  */
  379. dodiform()
  380. {
  381.   extern char bootstop;
  382.   extern char bootend;
  383.   int dev, v, w, i, br;
  384.   int modesel;            /* flag for mode select */
  385.   long cnt, hdsiz;
  386.   char *s, *d, *wgetstr();
  387.   char buf[10], bs[512], sendata[32];
  388.   char pnam[128];
  389.   char *seldev = "ACSI unit 0", *id = "XXXXX";
  390.   char *seldv =  "IDE  unit 0";
  391.   HINFO hinfo;
  392.   char devnames[NAMSIZ];    /* device type name buffer */
  393.   long nbad;
  394.   extern long gbslsiz(), nument(), dsmarkbad();
  395.   long pattern, temp, cyl;
  396.   long longrandom();
  397.   char pr_id[10];    /* partition scheme id */
  398.   int mask = 0x0001;
  399.   int set, scsidrv, bsiz, other = 0;
  400.   int page=4, spt, ret;
  401.   int head=0, domark;
  402.   
  403.   /*
  404.    * Throw up generic formatting/partition warning,
  405.    * then get physical dev they want to clobber.
  406.    */
  407.   yesscan = 0;
  408.   noinfo = 0;
  409.   for (i = 0; i < NAMSIZ; i++)
  410.       devnames[i] = "\0";
  411.   fwarning[FWARNCN].ob_state = NORMAL;
  412.   fwarning[FWARNOK].ob_state = NORMAL;
  413.   if (execform(fwarning) != FWARNOK) return BAILOUT;
  414.  
  415.   if ((dev = gphysdev()) < 0) {
  416.       return BAILOUT;
  417.   }
  418.   strcpy(id, "mn");
  419.   br = 0;
  420.  
  421.   /* display doing SCSI massage */
  422.  
  423.   inqfmt:
  424.   /* Get all available disk types from wincap 'mn' entries */  
  425.   wallents(devnames, id);
  426.   if (!*devnames)     {
  427.       noinfo = 1;
  428.       goto stfm;
  429.   }
  430.   
  431.   /* Shove format name text into buttons */
  432.   for (i = 0, s = devnames; i < 14 && *s; ++i) {
  433.       dsknames[pfmt[i]].ob_type = G_BUTTON;    /* button */
  434.       dsknames[pfmt[i]].ob_spec = (long)s;
  435.       dsknames[pfmt[i]].ob_state = NORMAL;
  436.       dsknames[pfmt[i]].ob_flags = SELECTABLE | RBUTTON;
  437.       while (*s++)
  438.     ;
  439.   }
  440.   other = i;                            /* the other button */
  441.   dsknames[pfmt[i]].ob_type = G_BUTTON;    /* button */
  442.   dsknames[pfmt[i]].ob_spec = "OTHER";
  443.   dsknames[pfmt[i]].ob_state = NORMAL;
  444.   dsknames[pfmt[i]].ob_flags = SELECTABLE | RBUTTON;
  445.   i++;
  446.  
  447.   /* rest of buttons are invisible and untouchable */
  448.   for (; i < 16; ++i) {
  449.       dsknames[pfmt[i]].ob_type = G_IBOX;    /* invisible box */
  450.       dsknames[pfmt[i]].ob_spec = 0;        /* no thickness */
  451.       dsknames[pfmt[i]].ob_state = DISABLED;    /* nobody home */
  452.       dsknames[pfmt[i]].ob_flags = NONE;        /* disabled */
  453.   }
  454.   
  455.   /* clean up rest of the form and throw it up */
  456.   dsknames[PFOK].ob_state = NORMAL;
  457.   dsknames[PFCN].ob_state = NORMAL;
  458.   if (execform(dsknames) != PFOK)
  459.     return BAILOUT;
  460.   
  461.   /* search for format they picked */
  462.   for (i = 0; i < 18; ++i)
  463.     if (dsknames[pfmt[i]].ob_state & SELECTED)
  464.       break;
  465.   if (i >= 18) {        /* nothing picked */
  466.       return BAILOUT;
  467.   } else if (other == i)    {  /* the OTHER button was selected */
  468.         noinfo = 1;
  469.       goto stfm;
  470.   }
  471.   
  472.     if ((!br) && (dev < 8))        {
  473.           if (wgetent(dsknames[pfmt[i]].ob_spec, "mn") == ERROR)    {
  474.             nofmt[NOSCHFMT].ob_spec = dsknames[pfmt[i]].ob_spec;
  475.             nofmt[NOSCHFMT].ob_state = NORMAL;
  476.             execform(nofmt, 0);
  477.             return ERROR;
  478.         }
  479.         if ((s = wgetstr("br")) != NULL)    {
  480.             strcpy(id, s);
  481.             br = 1;            /* processing the branch */
  482.             goto inqfmt;    /* start over */
  483.         }
  484.     }
  485.  
  486. stfm:
  487.     modesel = 1;
  488.   if(gfparm(dev, &noinfo, &modesel, &hinfo, dsknames[pfmt[i]].ob_spec,id)!= 0) {
  489.       return ERROR;
  490.   }
  491.   
  492.   /* get data pattern to test the disk */
  493.   if (wgetnum("dp", &pattern) != OK) {
  494.       pattern = longrandom();  /* can't find pattern from wincap, make one */
  495.   } else {
  496.       temp = pattern;
  497.       pattern <<= 16;    /* shift pattern to hi word */
  498.       pattern |= temp;
  499.   }
  500.  
  501.   if (dev > 15)    { /* IDE-AT drive */
  502.       br = dev - 16;
  503.   } else {            /* it is a scsi or acsi drive */
  504.       br = (dev > 7) ? (dev-8) : (dev);    /* minus 8 for the scsi drive number */
  505.   }
  506.  
  507.   /* asking the user do the marking bad or not */
  508.   mkornot[FMTYES].ob_state = NORMAL;
  509.   mkornot[FMTNO].ob_state = NORMAL;
  510.   domark = execform(mkornot);
  511.  
  512.   /*
  513.    * One last chance to bail out.
  514.    */
  515.   *seldev = 'A';
  516.   if (dev > 15)    { /* it is a IDE-AT drive */
  517.       seldev = seldv;
  518.   } else if (dev > 7)    { /* it is a SCSI drive */
  519.           *seldev = 'S';
  520.   }
  521.   *(seldev + 10) = br + '0';
  522.   (fmtfnl[FUNIT].ob_spec)->te_ptext = seldev;
  523.   fmtfnl[FMTYES].ob_state = NORMAL;
  524.   fmtfnl[FMTNO].ob_state = NORMAL;
  525.   if (execform(fmtfnl) != FMTYES) return BAILOUT;
  526.  
  527.   /* For REAL !! */  
  528.   dsplymsg(fmtmsg);
  529.  
  530.   bsl = 0L;
  531.   
  532.   /* Get size of Bad Sector List */
  533.   if ((bslsiz = gbslsiz(dev)) > 0L) {
  534.       /* Allocate memory for existing BSL */
  535.       if ((bsl = (BYTE *)mymalloc((int)bslsiz*512)) <= 0) {
  536.           ret = err(nomemory);
  537.           goto formend;
  538.       }
  539.       
  540.       /* Read in BSL */
  541.       if ((ret = rdbsl(dev)) != OK) {
  542.           /* Create a new BSL if current one is unusable */
  543.           if (creabsl(dev, NEW, 0L) != OK) {
  544.               ret = ERROR;
  545.               goto formend;
  546.           }
  547.       } else {
  548.             /* Remove USER BSL */
  549.             if (creabsl(dev, EXPAND, nument(VENDOR)) != OK) {
  550.                 ret = ERROR;
  551.                 goto formend;
  552.             }
  553.       }
  554.   } else if (bslsiz == 0L || bslsiz == ERROR) {    /* no bsl or read error */
  555.       if (creabsl(dev, NEW, 0L) != OK) {
  556.           ret = ERROR;
  557.           goto formend;
  558.       }
  559.   } else {    /* bslsiz == MDMERR; medium changed error */
  560.       ret = ERROR;
  561.       goto formend;
  562.   }
  563.   
  564.   /*
  565.    * In supervisor mode
  566.    * set disk format parameters
  567.    * and format the disk.
  568.    */
  569.   ostack = Super(NULL);
  570.   delay();
  571.   if (dev > 15)        { /* do the IDE-AT format */
  572.      if ((ret = fmtunt(dev)) != OK)    {
  573.       delay();
  574.         Super(ostack);
  575.       ret = errcode(dev);
  576.       if (tsterr(ret) != OK)
  577.           formaterr(dev);
  578.       ret = ERROR;
  579.     } else {
  580.         if (dev == 16)    {/* it is a master IDE-AT */
  581.             hdsiz = athead*atcyl*atspt; 
  582.         } 
  583.           disksiz = hdsiz;
  584.         delay();
  585.           Super(ostack);
  586.     }
  587.     goto formend;
  588.   }
  589.   set = typedev & (mask << dev);
  590.   scsidrv = typedrv & (mask << dev);
  591.   bsiz = ((set) || (scsidrv)) ? (16) : (22);
  592.   if (!noinfo)    {            /* there are info in the wincap */
  593.     if ((set) || (scsidrv))    {
  594.           v = mdsense(dev, 4, 0, 32, sendata);
  595.           delay();                    /* kludge delay */
  596.           sqms(dev, sendata);
  597.     } else {
  598.           if (modesel) {
  599.               v = ms(dev, &hinfo);    /* Yes, do noprmal mode set */
  600.         }
  601.     }
  602.       /* Find formatted capacity of drive */
  603.       hdsiz = (long)hinfo.hi_cc * (long)hinfo.hi_dhc * (long)hinfo.hi_spt;
  604.   }    else if (dev < 8)    {        /* No, do special mode set */
  605.     for (i = 0; i < 32; i++)
  606.         sendata[i] = 0;
  607.     if ((set) || (scsidrv))    {
  608.           if (mdsense(dev, 0, 0, bsiz, sendata) == OK)        {
  609.             if (hdsiz = get3bytes(sendata+5))    {
  610.                   delay();                    /* kludge delay */
  611.                 sqms(dev, sendata);
  612.                 v = OK;
  613.                 goto kkk;
  614.             }
  615.         }
  616.   redopg:
  617.         for (i = 0; i < 32; i++)
  618.             sendata[i] = 0;
  619.           v = mdsense(dev, page, 0, 32, sendata);
  620.           for (i = 0; i < 32; i++) /* the lenght of sendata */
  621.               if (sendata[i])
  622.                 break;
  623.           if ((i == 32) && (page == 4))    { /* no informations returned */
  624.             page = 3;
  625.             goto redopg;
  626.           } else if (i == 32)    {
  627.             ret = 111;
  628.               delay();                    /* kludge delay */
  629.               Super(ostack);
  630.             goto formend;
  631.         }
  632.         if (page == 4)    {
  633.             if (!(hdsiz = get3bytes(sendata+5)))    {
  634.                 page = 3;
  635.                 /*
  636.                 cyl = get3bytes(sendata+14);
  637.                 head = *(sendata+17);
  638.                 if ((!cyl) || (!head))    {
  639.                     ret = 111;
  640.                       delay();        
  641.                       Super(ostack);
  642.                     goto formend;
  643.                 }
  644.                 */
  645.                 sqms(dev, sendata);
  646.                 goto redopg;
  647.             }
  648.             sqms(dev, sendata);
  649.             goto kkk;
  650.         } 
  651.         if (!(hdsiz = get3bytes(sendata+5)))    {
  652.             /*
  653.             spt = getword(sendata+22);
  654.             hdsiz = cyl*head*spt;
  655.             */
  656.             if (!hdsiz)        {
  657.                 ret = 111;
  658.                   delay();                    /* kludge delay */
  659.                   Super(ostack);
  660.                 goto formend;
  661.             }
  662.         }
  663.         goto kkk;
  664.     } else {    /* it is the acsi drivers */
  665.           hdsiz = (long)hinfo.hi_cc * (long)hinfo.hi_dhc * (long)hinfo.hi_spt;
  666.           delay();                    /* kludge delay */
  667.           v = ms(dev, &hinfo);    /* Yes, do noprmal mode set */
  668.     }
  669.   }    else {
  670.         if ((v = readcap(dev, 0, (long)0, buf)) == OK)    {
  671.             if ((hdsiz = get4bytes(buf)))    {
  672.                 hdsiz += 1;
  673.                 ret = OK;
  674.                 goto kkk;
  675.             } 
  676.         } 
  677.           delay();                    /* kludge delay */
  678.         for (i = 0; i < 32; i++)
  679.             sendata[i] = 0;
  680.           if ((v=mdsense(dev, 0, 0, bsiz, sendata)) == OK)        {
  681.             if (hdsiz = get3bytes(sendata+5))    {
  682.                 ret = OK;
  683.                 goto kkk;
  684.             }
  685.         }
  686.         for (i = 0; i < 32; i++)
  687.             sendata[i] = 0;
  688.           delay();                    /* kludge delay */
  689.           if ((v=mdsense(dev, 4, 0, 32, sendata)) == OK)        {
  690.             if (hdsiz = get3bytes(sendata+5))    {
  691.                 ret = OK;
  692.                 goto kkk;
  693.             }
  694.         }
  695.         for (i = 0; i < 32; i++)
  696.             sendata[i] = 0;
  697.           delay();                    /* kludge delay */
  698.           if ((v=mdsense(dev, 3, 0, 32, sendata)) == OK)        {
  699.             if (hdsiz = get3bytes(sendata+5))    {
  700.                 ret = OK;
  701.                 goto kkk;
  702.             }
  703.         }
  704.         ret = 111;
  705.           delay();                    /* kludge delay */
  706.           Super(ostack);
  707.         goto formend;
  708.   }
  709. kkk:
  710.   disksiz = hdsiz;
  711.   delay();                    /* kludge delay */
  712.   if (v == OK)    {
  713.       v = format(dev, (UWORD)hinfo.hi_in);  /* format */
  714.   }
  715. lll:
  716.   delay();                    /* kludge delay */
  717.   Super(ostack);
  718.   
  719.   if (v != 0)  {
  720.       ret = errcode(dev);
  721.       if (tsterr(ret) != OK)
  722.           formaterr(dev);
  723.       ret = ERROR;
  724.       goto formend;
  725.   }
  726.   
  727.   ret = OK;
  728.   rebootp = 1;
  729. formend:
  730.   erasemsg();    /* Erase formatting box */
  731.   if (ret == 111)        /* HDX may not support this drive */
  732.           ret = err(needinfo);
  733.   if (ret < 0) {
  734.       if (bsl > 0) free(bsl);
  735.       return ERROR;
  736.   }
  737.   
  738.   /*------------------------------------------*
  739.    * Markbad the device destructively.          *
  740.    * Bad Sectors found are added to the BSL.  *
  741.    * Write BSL to device.              *
  742.    *------------------------------------------*/
  743.   if (domark == YESMK)    { /* need to do the markbad */
  744.       if ((nbad = dsmarkbad(dev, hdsiz, 1, pattern)) < 0) {
  745.           free(bsl);
  746.           return ERROR;
  747.       }
  748.   }
  749.   if (wrbsl(dev) != OK) {
  750.       free(bsl);
  751.       return ERROR;
  752.   }
  753.   free(bsl);
  754.  
  755.     
  756.   /*
  757.    * Install boot-stopper in sector image;
  758.    * write root sector to device.
  759.    * 6-13-88  Setting of soft format parameters in root sector sets
  760.    *        the hard disk size only.
  761.    */
  762.   fillbuf(bs, 512L, 0L);    /* create new root sector */
  763.   sbslparm(bs);            /* set BSL parameters */
  764.   if (modesel)    {
  765.       sfmtparm(bs, &hinfo);
  766.   } else {
  767.       sdisksiz(bs, disksiz);
  768.   }
  769.   for (d = bs, s = &bootstop, cnt = (long)(&bootend - &bootstop); --cnt;)
  770.     *d++ = *s++;
  771.   Protobt(bs, -1L, -1, 1);    /* make root sector executable */
  772.   
  773.   if ((ret = putroot(dev, bs, (SECTOR)0)) != OK) {
  774.       if (tsterr(ret) != OK)
  775.           err(rootwrit);
  776.       return ERROR;
  777.   }
  778.  
  779.   /*
  780.    * Make a copy of the default partition name.
  781.    * Figure out the partition scheme id.
  782.    */
  783.   if (!noinfo)    {
  784.       s = wgetstr("pt");
  785.       strcpy(pnam, s);
  786.   }
  787.   /* ??
  788.   figprid(disksiz, pr_id);
  789.   */
  790.   dodipart(dev, pnam, disksiz);
  791.   return OK;
  792. }
  793.  
  794.  
  795.  
  796. /*
  797.  * Handle [PARTITION] item;
  798.  * if `xdev' is -1, throw up dialog boxes;
  799.  * if `xdev' >= 0, just partition the dev,
  800.  * using `pnam' as the partition type, 
  801.  * and `pr_id' to search for the type.
  802.  *
  803.  */
  804. dodipart(xdev, pnam, hsize)
  805. int xdev;
  806. char *pnam;
  807. long hsize;
  808. {
  809.     int dev, i, ret =OK, fine;
  810.     int choice;
  811.     char *seldev = "ACSI unit 0";
  812.       char *seldv =  "IDE  unit 0";
  813.     char *s;
  814.     char bs[512];
  815.     PART *pinfo;
  816.     int tem1, tem2;
  817.     long disksiz;
  818.     int mask = 0x0001;
  819.  
  820.     if (xdev < 0) {
  821.     /*
  822.      * Throw up warning saying that partition is dangerous;
  823.      * then get physical dev they want to clobber.
  824.      */
  825.     pwarning[PWARNCN].ob_state = NORMAL;
  826.     pwarning[PWARNOK].ob_state = NORMAL;
  827.     if (execform(pwarning) != PWARNOK) return BAILOUT;
  828.     tformat = FALSE;
  829.     if ((dev = gphysdev()) < 0) {
  830.         return BAILOUT;
  831.     }
  832.     /*
  833.      * Let the user edit/pick partitions.
  834.      */
  835.     fine = 0;
  836.     while (!fine) {
  837.         if (sfigpart(bs, dev, (PART *)&pinfo) != OK)    {
  838.             if (pinfo > 0)    Mfree(pinfo);
  839.             return BAILOUT;
  840.         }
  841.         if ((ret = chkpart(dev, pinfo)) != OK) {
  842.             if (ret < 0)    {    /* size too big */
  843.                 err(nexsmem);
  844.             } else {    /* some other errors  */
  845.                 if (pinfo > 0)    Mfree(pinfo);
  846.                 return BAILOUT;
  847.             }
  848.         } else {
  849.             fine = 1;
  850.         }
  851.     }
  852.  
  853.       fine = dev;            /* default for the acsi unit */
  854.     *seldev = 'A';
  855.       if (dev > 15)    { /* it is a IDE-AT drive */
  856.         fine = dev - 16;
  857.         seldev = seldv;
  858.     } else if (dev > 7)     {    /* minus 8 for the scsi drive number */
  859.         fine = dev - 8;
  860.         *seldev = 'S';
  861.     }
  862.     *(seldev + 10) = fine + '0';
  863.  
  864.     /* Last chance to bail out */
  865.     (partfnl[PUNIT].ob_spec)->te_ptext = seldev;
  866.     partfnl[PARTYES].ob_state = NORMAL;
  867.     partfnl[PARTNO].ob_state = NORMAL;
  868.     if (execform(partfnl) != PARTYES)    {
  869.         if (pinfo > 0)    Mfree(pinfo);
  870.         return BAILOUT;
  871.     }
  872.  
  873.     } else {
  874.         /* ??
  875.         if ((!noinfo) && (!ttscsi) && (wgetent(pnam, pr_id) != OK)) {
  876.             nopart[NOSCHPOK].ob_state = NORMAL;
  877.             (nopart[NOSCHPR].ob_spec)->te_ptext = pnam;
  878.             execform(nopart);
  879.             return ERROR;
  880.         }
  881.         */
  882.         npart = 4;
  883.         ext = NO_EXT;    /* set the extended partition flag to not exists */
  884.         dev = xdev;
  885.         if ((pinfo = (PART *)Malloc((long)sizeof(PART)*npart)) <= 0)    {
  886.             err(nomemory);
  887.             if (pinfo > 0)    Mfree(pinfo);
  888.             return ERROR;
  889.         }
  890.         inipart(pinfo, npart);
  891.         npart = 0;
  892.         setpart(pinfo, pnam, hsize);
  893.         /* ??
  894.         if (ttscsi)        {     SCSI bus drive 
  895.             setpart(pinfo, hsize);
  896.         } else {             regular drvie 
  897.             for (i = 0; i < 4; ++i)
  898.                 fillpart(i, &pinfo[i]);
  899.         }
  900.         */
  901.     }
  902.  
  903.     /* For REAL!! */
  904.     dsplymsg(partmsg);
  905.     
  906.     bsl = 0L;
  907.     
  908.     /* Get size of BSL */
  909.     if ((bslsiz = gbslsiz(dev)) > 0L) {
  910.         /* Allocate memory for existing BSL */
  911.         if ((bsl = (BYTE *)mymalloc((int)bslsiz*512)) <= 0) {
  912.             ret = err(nomemory);
  913.             goto partend;
  914.         }
  915.             
  916.         /* Read in BSL */
  917.         if ((ret = rdbsl(dev)) != OK) {
  918.             if (ret == INVALID)
  919.                 err(cruptbsl);
  920.             ret = ERROR;
  921.             goto partend;
  922.         }
  923.     } else if (bslsiz == 0) {
  924.         ret = err(oldfmt);
  925.         goto partend;
  926.     } else if (bslsiz == ERROR) {
  927.         ret = err(rootread);
  928.         goto partend;
  929.     } else {
  930.         ret = ERROR;
  931.         goto partend;
  932.     }
  933.  
  934.     
  935.     /* Lay out partition headers */
  936.     if (spheader(dev, &pinfo[0]) != OK) {
  937.         ret = ERROR;
  938.         goto partend;
  939.     }
  940.     
  941.     if (wrbsl(dev) != OK) {        /* write BSL */
  942.         ret = ERROR;
  943.         goto partend;
  944.     }
  945.  
  946.     /* check and change the structure's id after 'spheader()' */
  947.     changeid(pinfo);
  948.  
  949.     /* Shove partition parms into root sector */
  950.     if ((ret = getroot(dev, bs, (SECTOR)0)) != 0)    {
  951.         if (tsterr(ret) != OK)
  952.             err(rootread);
  953.         ret = ERROR;
  954.         goto partend;
  955.     }
  956.  
  957.     if ((ret = stlayroot(bs, dev, pinfo)) != OK)    {
  958.         goto partend;
  959.     }
  960.     tem1 = npart;            /* save the number of partitions */
  961.     tem2 = ext;                /* save the index of extended partition */
  962.     if (rescan(1,0)) {        /* has to be here because map changed    */
  963.         ret = ERROR;        /* after partitions are moved around,    */
  964.         goto partend;        /* report medium change error.        */
  965.     }
  966.     npart = tem1;
  967.     ext = tem2;
  968.     /* Partition the device with parameters given in pinfo */
  969.     if (stlaybs(dev, &pinfo[0]) != OK)
  970.         ret = ERROR;
  971.     else
  972.         ret = OK;
  973.         
  974.     rebootp = 1;
  975.     /*  add on Jul 2, 90 for removable drive
  976.     if ((typedev & (mask << dev)))             it is a removable drive 
  977.         if (npart <= prevnpart)                 if less or equal than prevous 
  978.             rebootp = 0;                      partition, don't reboot 
  979.     change and add over on Jul 2, 90 for the removable drive on Oct 1, 90
  980.     if ((typedev & (mask << dev)))    {         it is a removable drive 
  981.         for (i = 0; i < 10; i++)     {
  982.             if (!mediach(dev))            
  983.                 break;
  984.             if (i == 10)
  985.                 rebootp = 1;
  986.             else
  987.                 rebootp = 0;
  988.         }
  989.     }
  990.     */
  991.     pnf = 1;        /* set the flag to just doing the partition */
  992. partend:
  993.     if (bsl > 0) free(bsl);
  994.     inipart(pinfo, npart);
  995.     if (pinfo > 0)    Mfree(pinfo);
  996.     erasemsg();
  997.     return (ret);
  998. }
  999.  
  1000.  
  1001. /*
  1002.  * get root sector informations and write them into that sector 
  1003.  */
  1004.  
  1005. stlayroot(bs, dev, part)
  1006. char *bs;
  1007. int dev;
  1008. PART *part;
  1009. {
  1010.     int i;
  1011.     UWORD sum = 0x1234;
  1012.     long cnt, disksiz, prvst;
  1013.     char *d, *s;
  1014.     extern char bootstop;
  1015.     extern char bootend;
  1016.  
  1017.     /* do the prime partition */
  1018.     spart(bs, part, 0, &prvst);    /* set ST partition parameters */
  1019.     /*
  1020.       sfmtparm(bs, &hinfo);
  1021.       for (d = bs, s = &bootstop, cnt = (long)(&bootend - &bootstop); --cnt;)
  1022.         *d++ = *s++;
  1023.     */
  1024.     sbslparm(bs);                /* set bsl parameters */
  1025.     Protobt(bs, -1L, -1, 1);        /* make root sector executable */
  1026.     if ((ret = putroot(dev, bs, (SECTOR)0)) != OK) {
  1027.         if (tsterr(ret) != OK)
  1028.             err(rootwrit);
  1029.         return(ERROR);
  1030.     }
  1031.     if (ext == NO_EXT)    return OK;        /* no extended partition */
  1032.     /* do the extended partitions */
  1033.     extsiz = part[ext].p_siz;
  1034.     for (i = 4; i < npart; i++)    {
  1035.         if (!(part[i].p_flg & P_EXISTS))    {     /* skip if not exists */
  1036.             return OK;
  1037.         }
  1038.         spart(bs, part, i, &prvst);    /* set IBM partition parameters */
  1039.         if ((ret = putroot(dev, bs, part[i].p_st)) != OK) {
  1040.             if (tsterr(ret) != OK)
  1041.                 err(rootwrit);
  1042.             return(ERROR);
  1043.         }
  1044.     }
  1045.     return OK;
  1046. }
  1047.  
  1048.  
  1049.  
  1050.  
  1051. /*
  1052.  * Put information into the root structure
  1053.  */
  1054.  
  1055. spart(image, pinfo, pnm, prvst)
  1056.  
  1057. char *image;            /* root sector buffer */
  1058. register PART *pinfo;    /* partition information */
  1059. int pnm;                /* partition number */
  1060. long *prvst;            /* The previous partition start sector */
  1061.  
  1062. {
  1063.     PART *rpart;
  1064.     long numcyl;
  1065.     int i, j;
  1066.  
  1067.     if (pnm)     {
  1068.         fillbuf(image, 512L, 0L);
  1069.     }
  1070.     rpart = &((RSECT *)(image + 0x200 - sizeof(RSECT)))->hd_p[0];
  1071.     if (pnm < 4)    {
  1072.         for (i = 0; i < NPARTS; i++, rpart++)    {
  1073.             if (pinfo->p_flg & P_EXISTS)    {
  1074.                 rpart->p_flg = P_EXISTS;
  1075.                 for (j = 0; j < 3; j++)
  1076.                     rpart->p_id[j] = pinfo->p_id[j];
  1077.                 rpart->p_st = pinfo->p_st;
  1078.                 rpart->p_siz = pinfo->p_siz;
  1079.             } else {
  1080.                 rpart->p_flg = 0;
  1081.                 for (j = 0; j < 3; j++)
  1082.                     rpart->p_id[j] = 0;
  1083.                 rpart->p_st = 0L;
  1084.                 rpart->p_siz = 0L;
  1085.             }
  1086.             pinfo++;
  1087.         }
  1088.  
  1089.     } else {    /* pnm => 4 */
  1090.         rpart->p_flg = pinfo[pnm].p_flg;
  1091.         for (j = 0; j < 3; j++)
  1092.             rpart->p_id[j] = pinfo[pnm].p_id[j];
  1093.         rpart->p_st = ROOTSECT;
  1094.         rpart->p_siz = pinfo[pnm].p_siz - ROOTSECT;
  1095.         rpart++;
  1096.         if (((pnm + 1) != npart) && (pinfo[pnm+1].p_flg & P_EXISTS)) { 
  1097.             /* need extened partition */
  1098.             rpart->p_flg = P_EXISTS;
  1099.             rpart->p_id[0] = 'X';
  1100.             rpart->p_id[1] = 'G';
  1101.             rpart->p_id[2] = 'M';
  1102.             rpart->p_siz = pinfo[pnm+1].p_siz;
  1103.             rpart->p_st = (pnm == 4) ? (pinfo[4].p_siz) :
  1104.                                     (pinfo[pnm].p_siz + *prvst);
  1105.             *prvst = rpart->p_st;
  1106.         }
  1107.  
  1108.     }
  1109. }
  1110.  
  1111.  
  1112.  
  1113. /*
  1114.  * Setup partitions on the disk;
  1115.  * write boot sectors and zero FATs and root directories.
  1116.  *
  1117.  */
  1118. stlaybs(physdev, pinfo)
  1119. int physdev;
  1120. register PART *pinfo;
  1121. {
  1122.     int i, ldev, ret;
  1123.     int kindfat;
  1124.     SECTOR data, nsect;
  1125.     char *devno="X";
  1126.     long ndirs;
  1127.     UWORD fatsiz;
  1128.     BOOT *bs;
  1129.     long serialno;
  1130.     extern long longrandom();
  1131.     extern long cell();
  1132.     char *buf;
  1133.     long size;
  1134.  
  1135.     if ((bslsiz = gbslsiz(physdev)) < 0L) {
  1136.         if (bslsiz == ERROR)
  1137.             err(rootread);
  1138.         return ERROR;
  1139.     }
  1140.     /* SCAN_BS: pinfo is for scan() and laybs() use */
  1141.     if (ext != NO_EXT)    sortpart(pinfo, SCAN_BS);    
  1142.  
  1143.     for (i = 0; i < npart; ++i, ++pinfo) {
  1144.         
  1145.         /* don't care if partition does not exist */
  1146.         if (!(pinfo->p_flg & P_EXISTS)) {
  1147.             return OK;
  1148.         }
  1149.  
  1150.  
  1151.     /*
  1152.      * Compute boot sector parameters.
  1153.      */
  1154.         if (pinfo->p_siz > disksiz) {        /* partition >? disk size */
  1155.             *devno = i + '0';
  1156.             (part2big[BGPART].ob_spec)->te_ptext = devno;
  1157.             part2big[BGPARTOK].ob_state = NORMAL;
  1158.             execform(part2big);
  1159.             return ERROR;
  1160.         }
  1161.  
  1162.     /* estimat the bps */
  1163.     /* MAXSECT = 16MB - 8 */
  1164.     bps = cell((pinfo->p_siz-7)*BPS, (long)MAXSECT);
  1165.  
  1166.     /* the real bps */
  1167.     bps = BPS * n2power((UWORD)cell(bps, (long)BPS));
  1168.     ratio = bps / BPS;
  1169.     nsect = pinfo->p_siz / ratio;
  1170.  
  1171.     size = (long)BPS * ratio;
  1172.     if ((buf = (char *)Malloc(size)) <= 0)    {
  1173.         err(nomemory);
  1174.         if (buf > 0) Mfree((long)buf);
  1175.         return ERROR;
  1176.     }
  1177.  
  1178.     /*
  1179.      * Install entries in boot sector image;
  1180.      * force sector checksum to zero (non-executable);
  1181.      * write boot sector to media.
  1182.      *
  1183.       *    512 bytes/sector
  1184.      *    2 or 4 sectors/cluster (partition > 16Mb has 4 spc)
  1185.      *    1 reserved sector (for boot)
  1186.      *    2 FATs
  1187.      *    ... dir slots
  1188.      *    ... # sectors
  1189.      *    F8 means media is a hard disk
  1190.      *    ... FAT size
  1191.      *
  1192.      */
  1193.      
  1194.     /* Make a clean boot sector */
  1195.     fillbuf(buf, bps, 0L);
  1196.     bs = (BOOT *)buf;
  1197.         
  1198.  
  1199.     /* bytes per sector */
  1200.     iw((UWORD *)&bs->b_bps[0], (UWORD)bps);
  1201.     
  1202.     /* sectors per cluster */
  1203.     bs->b_spc = SPC;
  1204.         
  1205.     /* number of reserved sectors */
  1206.     iw((UWORD *)&bs->b_res[0], (UWORD)1);
  1207.     
  1208.     /* number of FATs */
  1209.     bs->b_nfats = 2;
  1210.     
  1211.  
  1212.     /*
  1213.      * Compute root directory size
  1214.      * 256 entries, plus fudge on devs > 10Mb
  1215.      */
  1216.     if (pinfo->p_siz < 0x5000L) ndirs = NUMEN;
  1217.     else ndirs = nsect / 80;    /* 1 dir entry per 80 sectors */
  1218.     /* round to nearest sector */
  1219.     ndirs = (ndirs + ((UWORD)bps/BPDIR - 1)) & ~((UWORD)bps/BPDIR - 1);    
  1220.     iw((UWORD *)&bs->b_ndirs[0], (UWORD)ndirs);
  1221.     
  1222.     /* number of sectors on media (partition) */
  1223.     iw((UWORD *)&bs->b_nsects[0], (UWORD)nsect);
  1224.  
  1225.     /* media descriptor */
  1226.     bs->b_media = 0xf8;
  1227.  
  1228.     /*--------------------------------------------------------------*
  1229.      * Compute FAT size                        *
  1230.      *                                *
  1231.      * Num entries to map the entire partition            *
  1232.      *    = partition's size in clusters                *
  1233.      *    = partition's size in sectors / spc            *
  1234.      *                                *
  1235.      * Num entries in FAT                        *
  1236.      *    = Num entries to map partition + reserved entries    *
  1237.      *    = (partition's size in sectors / spc) + 2        *
  1238.      *                                *
  1239.      * Num sectors FAT occupies                    *
  1240.      *    = Num entries in FAT / Num entries of FAT per sector    *
  1241.      *    = Num entries in FAT / (512 / 2)    <16-bit FAT>    *
  1242.      *    = ((partition's size in sectors / spc) + 2) / 256 + 1    *
  1243.      *                        <+1 to round up>    *
  1244.      *--------------------------------------------------------------*/
  1245.     fatsiz = ((((nsect / bs->b_spc) + 2) * 2) / bps) + 1;
  1246.     iw((UWORD *)&bs->b_spf[0], (UWORD)fatsiz);
  1247.  
  1248.     /* write the serial number to the bs */ 
  1249.     Protobt(bs, 0x01000000, -1, -1);
  1250.  
  1251.     /*
  1252.      * Write partition's boot sector
  1253.      */
  1254.     forcesum((UWORD *)buf, (UWORD)0);    /* force image checksum */
  1255.     if ((ret = wrsects(physdev,(UWORD)ratio,buf,(SECTOR)pinfo->p_st))!= OK) {
  1256.         if (tsterr(ret) != OK)
  1257.             err(bootwrit);
  1258.         return ERROR;
  1259.     }
  1260.  
  1261.     /*
  1262.      * Zero the partition
  1263.      */
  1264.     if ((ret = zerosect(physdev, (SECTOR)(pinfo->p_st+ratio),
  1265.              ((UWORD)((fatsiz*2 + ndirs*BPDIR/bps) * ratio)))) != OK) {
  1266.         if (tsterr(ret) != OK)
  1267.             err(hdrwrite);
  1268.         return ERROR;
  1269.     }
  1270.              
  1271.     /*
  1272.      * Make first 2 entries in FATs more IBM-like.
  1273.      */
  1274.     if ((ret = rdsects(physdev,(UWORD)ratio,buf,
  1275.                         (SECTOR)(pinfo->p_st+ratio)))!= 0){
  1276.         if (tsterr(ret) != OK)
  1277.             err(fatread);
  1278.         return ERROR;
  1279.     }
  1280.     *(UWORD *)&buf[0] = 0xf8ff;
  1281.     *(UWORD *)&buf[2] = 0xffff;
  1282.     if ((ret = wrsects(physdev,(UWORD)ratio,
  1283.                         buf,(SECTOR)(pinfo->p_st+ratio)))!= 0 ||
  1284.         (ret = wrsects(physdev,(UWORD)ratio,buf,
  1285.                         (SECTOR)(pinfo->p_st+ratio+fatsiz*ratio)))
  1286.         != 0) {
  1287.         if (tsterr(ret) != OK)
  1288.             err(fatwrite);
  1289.         return ERROR;
  1290.     }
  1291.  
  1292.     /*
  1293.      * Mark bad sectors recorded in the BSL into the FATs.
  1294.      * Calculating parameters:
  1295.      *    ldev - from physdev and i.
  1296.      *    fat0 - always equals 1.
  1297.      *    fatsiz - calculated above.
  1298.      *    data - starts after the boot sector, 2 FATs and rootdir.
  1299.      */
  1300.  
  1301.         if (bslsiz > 0) {
  1302.             if ((ldev = phys2log(physdev, i)) == ERROR)
  1303.                 return parterr(physdev);
  1304.             data = (SECTOR)1 + (SECTOR)(fatsiz*2) + (SECTOR)(ndirs*BPDIR/bps);
  1305.             bsl2fat(ldev, (SECTOR)ratio, (UWORD)(fatsiz*ratio), 
  1306.                                                 data*ratio, MEDIA);
  1307.         }
  1308.         if (buf > 0) Mfree((long)buf);
  1309.     }
  1310.     return OK;
  1311. }
  1312.  
  1313.  
  1314.  
  1315.  
  1316. /*
  1317.  * Handle [ZERO] item.
  1318.  *
  1319.  */
  1320. dodizero()
  1321. {
  1322.     int ldev, ret;
  1323.     char *seldev = "X";
  1324.     int i; 
  1325.  
  1326.     zwarning[ZWOK].ob_state = NORMAL;
  1327.     zwarning[ZWCN].ob_state = NORMAL;
  1328.     if (execform(zwarning) != ZWOK)
  1329.     return BAILOUT;
  1330.     if (showmany)    err(manyldev);
  1331.  
  1332.     if ((ldev = glogdev()) < 0) return BAILOUT;
  1333.  
  1334.     /* Find out if logical device has assumed parameters */
  1335.     if (chkparm(ldev) != OK) {
  1336.         wronparm[WRONOK].ob_state = NORMAL;
  1337.     execform(wronparm);
  1338.     return ERROR;
  1339.     }
  1340.         
  1341.     *seldev = ldev;
  1342.     (zerofnl[ZDRV].ob_spec)->te_ptext = seldev;
  1343.     strcat((zerofnl[ZDRV].ob_spec)->te_ptext, ":");
  1344.     zerofnl[ZYES].ob_state = NORMAL;
  1345.     zerofnl[ZNO].ob_state = NORMAL;
  1346.     if (execform(zerofnl) != ZYES)  return BAILOUT;
  1347.  
  1348.     dsplymsg(zeromsg);
  1349.     if (zero(ldev) == OK) {
  1350.     if (!rebootp) {
  1351.         for (i = 0; i < 10; i++) {
  1352.         if (!mediach(ldev-'A')) break;
  1353.         }
  1354.         if (i == 10) {
  1355.             rebootp = 1;
  1356.         err(mdach);
  1357.             }
  1358.     }
  1359.     }
  1360.     erasemsg();
  1361. }
  1362.  
  1363.  
  1364. /*
  1365.  * Handle [MARKBAD] item.
  1366.  *
  1367.  */
  1368. dodimark()
  1369. {
  1370.     int ldev, ret;
  1371.     int i;
  1372.  
  1373.     mwarning[MWARNOK].ob_state = NORMAL;
  1374.     mwarning[MWARNCN].ob_state = NORMAL;
  1375.     if (execform(mwarning) == MWARNCN)
  1376.         return BAILOUT;
  1377.     if (showmany)    err(manyldev);
  1378.  
  1379.     if ((ldev = glogdev()) < 0)
  1380.         return BAILOUT;
  1381.         
  1382.     /* Find out if logical device has assumed parameters */
  1383.     if (chkparm(ldev) != OK) {
  1384.         wronparm[WRONOK].ob_state = NORMAL;
  1385.     execform(wronparm);
  1386.     return ERROR;
  1387.     }
  1388.          
  1389.     dsplymsg(lmrkmsg);
  1390.     if (markbad(ldev) != OK) {
  1391.         erasemsg();
  1392.     } else {
  1393.         if (!rebootp) {
  1394.         for (i = 0; i < 10; i++) {
  1395.         if (!mediach(ldev-'A')) break;
  1396.         }
  1397.         if (i == 10) {
  1398.             rebootp = 1;
  1399.         err(mdach);
  1400.             }
  1401.         }
  1402.     }
  1403. }
  1404.  
  1405.  
  1406. /*
  1407.  * Map from button in ship dial.
  1408.  */
  1409. int sdev[] = {
  1410.     SDEV0, SDEV1, SDEV2, SDEV3,
  1411.     SDEV4, SDEV5, SDEV6, SDEV7
  1412. };
  1413.  
  1414. /*
  1415.  * Ship selected devices.
  1416.  */
  1417. dodiship()
  1418. {
  1419.   int i, seldev[24], selected=0;
  1420.   int j, endup, index=0, unit=8, ret;
  1421.   
  1422.     /* Set up the dialog box for SCSI or ACSI driver selection */
  1423.     typedial[SCSIYES].ob_state = NORMAL;
  1424.     typedial[ACSIYES].ob_state = NORMAL;
  1425.     typedial[IDEYES].ob_state = NORMAL;
  1426.     /* check which type of unit was selected */
  1427.     if ((!ttscsi) && (noacsi))    { /* don't need select */
  1428.         index = 16;
  1429.         unit = 2;
  1430.     } else if ((!ttscsi) && (!atexst))    { /* don't need select */
  1431.         ;
  1432.     } else if ((!atexst) && (noacsi))    { /* don't need select */
  1433.         index = 8;
  1434.     } else {
  1435.         if (!ttscsi)    {
  1436.             typedial[SCSIYES].ob_state = DISABLED;
  1437.         } else if (!atexst)    {
  1438.             typedial[IDEYES].ob_state = DISABLED;
  1439.         } else if (noacsi)    {
  1440.             typedial[ACSIYES].ob_state = DISABLED;
  1441.         }
  1442.         if ((ret = execform(typedial)) == SCSIYES)    {
  1443.             index = 8;
  1444.         } else if (ret == IDEYES)    {
  1445.             index = 16;
  1446.             unit = 2;
  1447.         }
  1448.     } 
  1449.     
  1450.   /* Throw up generic shipping warning. */
  1451.   shipdial[SWARNCN].ob_state = NORMAL;
  1452.   shipdial[SWARNOK].ob_state = NORMAL;
  1453.   if (execform(shipdial) != SWARNOK) return BAILOUT;
  1454.   
  1455.   /* Device(s) selected? */
  1456.   shipdev[SDEVOK].ob_state = NORMAL;
  1457.   shipdev[SDEVCN].ob_state = NORMAL;
  1458.   for(i = 0; i < 8; i++)     /* indicate what's alive */
  1459.         shipdev[sdev[i]].ob_state = DISABLED;
  1460.   endup = index + unit;
  1461.   for(i = index, j = 0; i < endup; i++, j++)     /* indicate what's alive */
  1462.         if (livedevs[i])
  1463.             shipdev[sdev[j]].ob_state = NORMAL | SHADOWED;
  1464.   
  1465.   if (execform(shipdev) != SDEVOK)
  1466.       return BAILOUT;
  1467.       
  1468.   for(i = 0; i < 8; i++) {    /* search for selected unit */
  1469.       if (shipdev[sdev[i]].ob_state & SELECTED) {
  1470.           seldev[i+index] = 1;
  1471.           selected++;
  1472.       } else {
  1473.             seldev[i+index] = 0;
  1474.       }
  1475.   }
  1476.   
  1477.   if (!selected) return BAILOUT;    /* nothing is selected */
  1478.   
  1479.   /* Throw up final shipping warning. */
  1480.   shipfnl[SFNLCN].ob_state = NORMAL;
  1481.   shipfnl[SFNLOK].ob_state = NORMAL;
  1482.   if (execform(shipfnl) != SFNLOK) return BAILOUT;
  1483.   
  1484.   /* For REAL!!! */
  1485.   /* Ship selected devices */
  1486.   for (i = 0; i < MAXPHYSDEV; i++) {
  1487.       if (seldev[i])
  1488.           ship(i);
  1489.   }
  1490.   
  1491.   /* Put out final message about turning off hard disks */
  1492.   scommand[TRNOFFOK].ob_state = NORMAL;
  1493.   execform(scommand);
  1494. }
  1495.  
  1496.  
  1497.  
  1498. /*
  1499.  * Translate unit number to tree index.
  1500.  *
  1501.  */
  1502. static int physxlat[] = {
  1503.     UNIT0, UNIT1, UNIT2, UNIT3,
  1504.     UNIT4, UNIT5, UNIT6, UNIT7
  1505. };
  1506.  
  1507.  
  1508. /*
  1509.  * Get physical device#,
  1510.  * return devno or -1.
  1511.  *
  1512.  */
  1513. gphysdev()
  1514. {
  1515.     int i, j, endup, start, index=0;
  1516.     int ret, unit=8;
  1517.  
  1518.     /* Set up the dialog box for SCSI or ACSI or IDE-AT driver selection */
  1519. redogphy:
  1520.     typedial[SCSIYES].ob_state = NORMAL;
  1521.     typedial[ACSIYES].ob_state = NORMAL;
  1522.     typedial[IDEYES].ob_state = NORMAL;
  1523.     /* check which type of unit was selected */
  1524.     if ((!ttscsi) && (noacsi))    { /* don't need select */
  1525.         index = 16;
  1526.         unit = 2;
  1527.     } else if ((!ttscsi) && (!atexst))    { /* don't need select */
  1528.         ;
  1529.     } else if ((!atexst) && (noacsi))    { /* don't need select */
  1530.         index = 8;
  1531.     } else {
  1532.         if (!ttscsi)    {
  1533.             typedial[SCSIYES].ob_state = DISABLED;
  1534.         } else if (!atexst)    {
  1535.             typedial[IDEYES].ob_state = DISABLED;
  1536.         } else if (noacsi)    {
  1537.             typedial[ACSIYES].ob_state = DISABLED;
  1538.         }
  1539.         if ((ret = execform(typedial)) == SCSIYES)    {
  1540.             index = 8;
  1541.         } else if (ret == IDEYES)    {
  1542.             index = 16;
  1543.             unit = 2;
  1544.         }
  1545.     } 
  1546.     /*
  1547.      * Clean up and exec object;
  1548.      * shadow devs we KNOW are there.
  1549.      */
  1550.     physdial[PHYSOK].ob_state = NORMAL;
  1551.     physdial[PHYSCN].ob_state = NORMAL;
  1552.     
  1553.     if (tformat == TRUE) {
  1554.         start = 1;        /* start initializing at unit 0 */
  1555.         physdial[physxlat[0]].ob_state = NORMAL;
  1556.     } else {
  1557.         start = 0;        /* start initializing at unit 1 */
  1558.     }
  1559.     
  1560.     endup = index + unit;
  1561.     for (i = start; i < 8; ++i)
  1562.         physdial[physxlat[i]].ob_state = DISABLED;
  1563.     /*
  1564.     if (ttscsi)             the hard drive is a SCSI drive 
  1565.         physdial[physxlat[8]].ob_state = NORMAL;
  1566.     */
  1567.     for (i = index, j = 0; i < endup; ++i, j++)
  1568.         if (livedevs[i])
  1569.             physdial[physxlat[j]].ob_state = NORMAL | SHADOWED;
  1570.  
  1571.     if (execform(physdial) != PHYSOK)
  1572.         return ERROR;
  1573.      
  1574.     /* search for the selected unit */
  1575.     for (i = 0; i < unit; ++i)
  1576.         if (physdial[physxlat[i]].ob_state & SELECTED)    {
  1577.             if (livedevs[index+i])
  1578.                 return(index+i);
  1579.             else    {    
  1580.                 form_alart(1, nodev);
  1581.                 goto redogphy;
  1582.             }
  1583.         }
  1584.  
  1585.  
  1586.     return ERROR;            /* if no object selected */
  1587. }
  1588.  
  1589.  
  1590. /*
  1591.  * Translate from logical device number
  1592.  * to object number in logical device
  1593.  * dialouge box.
  1594.  */
  1595. int logxlat[] = {
  1596.     CCOLON, DCOLON, ECOLON, FCOLON,
  1597.     GCOLON, HCOLON, ICOLON, JCOLON,
  1598.     KCOLON, LCOLON, MCOLON, NCOLON,
  1599.     OCOLON, PCOLON
  1600. };
  1601.  
  1602.  
  1603. /*
  1604.  * Get logical device,
  1605.  * return 'C'...'P'
  1606.  * or -1.
  1607.  *
  1608.  */
  1609. glogdev()
  1610. {
  1611.     int i, flg;
  1612.  
  1613.     /*
  1614.      * Setup tree; selectively enable drive buttons
  1615.      * and so on.
  1616.      */
  1617.     logdial[LOGOK].ob_state = NORMAL;
  1618.     logdial[LOGCN].ob_state = NORMAL;
  1619.     for (i = 0; i < MAXLOGDEVS; ++i) {
  1620.     if (logmap[i].lm_physdev < 0)
  1621.         flg = DISABLED;
  1622.         else flg = NORMAL;
  1623.     logdial[logxlat[i]].ob_state = flg;
  1624.     }
  1625.  
  1626.     if (execform(logdial) != LOGOK) return -1;
  1627.  
  1628.     for (i = 0; i < MAXLOGDEVS; ++i)
  1629.     if (logdial[logxlat[i]].ob_state & SELECTED)
  1630.         return i + 'C';
  1631.  
  1632.     return -1;
  1633. }
  1634.  
  1635.  
  1636. /*
  1637.  * Open virtual workstation.
  1638.  *
  1639.  */
  1640. open_vwork()
  1641. {
  1642.     int i;
  1643.  
  1644.     for (i = 0; i < 10;)
  1645.     work_in[i++] = 1;
  1646.     work_in[10] = 2;
  1647.     handle = phys_handle;
  1648.     v_opnvwk(work_in, &handle, work_out);
  1649. }
  1650.  
  1651.  
  1652. /*
  1653.  * Find and redraw all clipping rectangles
  1654.  *
  1655.  */
  1656. do_redraw(xc, yc, wc, hc)
  1657. int xc, yc, wc, hc;
  1658. {
  1659.     GRECT t1, t2;
  1660.     int temp[4];
  1661.  
  1662.     hide_mouse();
  1663.     t2.g_x=xc;
  1664.     t2.g_y=yc;
  1665.     t2.g_w=wc;
  1666.     t2.g_h=hc;
  1667.     vsf_interior(handle, 1);
  1668.     vsf_color(handle, 0);
  1669.     wind_get(wi_handle, WF_FIRSTXYWH, &t1.g_x, &t1.g_y, &t1.g_w, &t1.g_h);
  1670.     while (t1.g_w && t1.g_h) {
  1671.     if (rc_intersect(&t2, &t1)) {
  1672.         set_clip(t1.g_x, t1.g_y, t1.g_w, t1.g_h);
  1673.         temp[0] = xwork;
  1674.         temp[1] = ywork;
  1675.         temp[2] = xwork + wwork - 1;
  1676.         temp[3] = ywork + hwork - 1;
  1677.         v_bar(handle, temp);
  1678.     }
  1679.     wind_get(wi_handle, WF_NEXTXYWH, &t1.g_x, &t1.g_y, &t1.g_w, &t1.g_h);
  1680.     }
  1681.  
  1682.     show_mouse();
  1683. }
  1684.  
  1685.  
  1686. /*
  1687.  * Hide the mouse.
  1688.  *
  1689.  */
  1690. hide_mouse()
  1691. {
  1692.     if (!hidden) {
  1693.     graf_mouse(M_OFF, 0L);
  1694.     hidden = TRUE;
  1695.     }
  1696. }
  1697.  
  1698.  
  1699. /*
  1700.  * Show the mouse.
  1701.  *
  1702.  */
  1703. show_mouse() 
  1704. {
  1705.     if (hidden) {
  1706.     graf_mouse(M_ON, 0L);
  1707.     hidden = FALSE;
  1708.     }
  1709. }
  1710.  
  1711.  
  1712. /*
  1713.  * Set clipping rectangle.
  1714.  *
  1715.  */
  1716. set_clip(x, y, w, h)
  1717. int x, y, w, h;
  1718. {
  1719.     int clip[4];
  1720.  
  1721.     clip[0] = x;
  1722.     clip[1] = y;
  1723.     clip[2] = x + w;
  1724.     clip[3] = y + h;
  1725.     vs_clip(handle, 1, clip);
  1726. }
  1727.  
  1728.  
  1729. /*
  1730.  * "Execute" form,
  1731.  * return thingy that caused the exit.
  1732.  *
  1733.  */
  1734. execform(tree)
  1735. OBJECT tree[];
  1736. {
  1737.     int thingy;
  1738.  
  1739.     ARROW_MOUSE;
  1740.     dsplymsg(tree);
  1741.     thingy = form_do(tree, 0);
  1742.     erasemsg();
  1743.     BEE_MOUSE;
  1744.     return thingy;
  1745. }
  1746.  
  1747.  
  1748. /*
  1749.  *  Display a dialogue box on the screen.
  1750.  *    Input:
  1751.  *        tree - object tree for dialogue box to be displayed.
  1752.  *    Output:
  1753.  *        formw, formh, sx, sy, lx, ly - dimensions of box.
  1754.  */
  1755. dsplymsg(tree)
  1756. OBJECT *tree;
  1757. {
  1758.     form_center(tree,&lx, &ly, &formw, &formh);
  1759.  
  1760.     /*
  1761.     sx = lx + formw / 2;
  1762.     sy = ly + formh / 2;
  1763.     */
  1764.     
  1765.     form_dial(1, 0, 0, 0, 0, lx, ly, formw, formh);
  1766.     objc_draw(tree, 0, MAX_DEPTH, 0, 0, wdesk, hdesk);
  1767. }
  1768.  
  1769.  
  1770. /*
  1771.  *  Erase a dialogue box from the screen.
  1772.  *    Input:
  1773.  *        formw, formh, sx, sy, lx, ly - dimensions of box.
  1774.  */
  1775. erasemsg()
  1776. {
  1777.     form_dial(3, 0, 0, 0, 0, lx, ly, formw, formh);
  1778. }
  1779.  
  1780.  
  1781.  
  1782. /*
  1783.  *  Make a long (4-byte) random.
  1784.  */ 
  1785. long
  1786. longrandom()
  1787. {
  1788.     long pattern;
  1789.     
  1790.     pattern = Random();
  1791.     pattern <<= 16;
  1792.     pattern ^= Random();
  1793.     
  1794.     return (pattern);
  1795. }
  1796.  
  1797. changeid(part)
  1798. PART *part;
  1799. {
  1800.     int i;
  1801.     long psiz;
  1802.  
  1803.     for(i = 0; i < npart; i++)    {
  1804.         if (i == ext)    continue;
  1805.         if (!(part[i].p_flg & P_EXISTS)) return OK;
  1806.         if (i > 3)    {
  1807.             psiz = part[i].p_siz - ROOTSECT;
  1808.         } else {
  1809.             psiz = part[i].p_siz;
  1810.         }
  1811.         if (psiz < MB16)    {
  1812.             part[i].p_id[0] = 'G';
  1813.             part[i].p_id[1] = 'E';
  1814.             part[i].p_id[2] = 'M';
  1815.         } else {
  1816.             part[i].p_id[0] = 'B';
  1817.             part[i].p_id[1] = 'G';
  1818.             part[i].p_id[2] = 'M';
  1819.         }
  1820.     }
  1821. }
  1822.  
  1823.