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 / HDX504A / SECT.BAK < prev    next >
Encoding:
Text File  |  2001-02-09  |  26.5 KB  |  1,083 lines

  1. /* sect.c */
  2.  
  3. /* 
  4.  * Aug-23-88 jye. Change and add codes so that can be used for MS-DOS
  5.  * Dec-20-89 jye. Free a bug that HDX gives a error message when CD-ROM 
  6.  *                  is busy. 
  7.  * Feb-11-93 jye. changed the size of the 'sentdate' buff to 56 bytes 
  8.  *                  for the 'inquiry', this will fit some hard drives. (Ex.
  9.  *                  IBM OME 0663E15)
  10.  * May-10-93 jye. Fix a bug that can't format or partition any externally
  11.  *                  connected SCSI drive if the Falcon has no internal hard-
  12.  *                  disk. Added codes in rescan()
  13.  * May-25-93 jye. Added code to check if it is removabel drive, then send the
  14.  *                  'mdsense' commend with page code 0x2e and allocation length
  15.  *                  42 to unlock the floptical drive.
  16.  * Jul-15-93 jye. Fix a bug that didn't set the flag for the scsi drive in the
  17.  *                   MEGA STE computer.
  18.  */
  19.  
  20. #include "obdefs.h"
  21. #include "osbind.h"
  22. #include "mydefs.h"
  23. #include "part.h"
  24. #include "hdx.h"
  25. #include "addr.h"
  26. #include "myerror.h"
  27.  
  28. #define    ZBUFSIZ    0x4000        /* about 16k == 32 sectors */
  29. #define    ZCOUNT    (ZBUFSIZ/0x200)    /* ZCOUNT = 32 */
  30. #define MAXUNITS 16            /* max number of logical units */
  31.  
  32. #define PUNINFO struct _punifno
  33. PUNINFO {
  34.         WORD puns;    /* number of physical units */
  35.         BYTE pun[MAXUNITS];
  36.         LONG partition_start[MAXUNITS]; /* offset to partition on */
  37.                                         /* physical unit */
  38. };
  39. extern long ostack;        /* old stack pointer */
  40. extern UWORD errcode();        /* function to return error code */
  41. extern int yesscan;        /* the flag for the func. IBMGPART use */
  42. extern long sptrk;        /* the sector per track */
  43. extern int npart;        /* the number of partitions */
  44. extern int ext;            /* the index of extended partition */
  45. extern int extend;        /* the index of end extended partition */
  46. extern int showmany;    /* the flag for show the too many device alert box */
  47. extern char ttscsi;        /* the flag for SCSI if set */
  48. extern char spscsixst;    /* set for the sparrow scsi exist */
  49. extern int needscan;    /* TRUE: if it is the first time to scan the units */
  50. extern int athead;        /* the # of data heads on the AT drive */
  51. extern int atcyl;        /* the # of cylinders on the AT drive */
  52. extern int atspt;        /* the # of sectors per track on the AT drive */
  53. extern int noacsi;        /* set for no ACSI drive in the system */
  54. extern char slwacsi;    /* 1: set for slow acsi device */
  55. extern char *drvid[];    /* for the id of the devices */
  56. /*
  57.  * Logical-to-dev+partition mapping table.
  58.  */
  59. int nlogdevs;                /* # logical devices */
  60. LOGMAP logmap[EXTRALOGD];    /* logical dev map */
  61. int livedevs[MAXPHYSDEVS];    /* live devs flags; 1: device is alive */
  62. int idevs[16];                /* the devs have id flags; 1: device has id */
  63. int typedev = 0x0000;        /* if set, driver is a removable driver */
  64. int typedrv = 0x0000;        /* if set, driver is a SCSI driver */
  65. int atexst;                    /* AT drive exists */
  66. int slvexst;                /* AT slave drive exists */
  67. char useblit;                /* set for it is not the stbook drive */
  68.  
  69.  
  70. /*
  71.  * Rebuild logical-to-physical mapping
  72.  * by reading and interpreting the root
  73.  * blocks for all physical devs.
  74.  *
  75.  */
  76.  
  77. rescan(flag, fnp)
  78.  
  79. int flag;    /* 0: don't report medium change error; */
  80.             /* non-0: report medium change error; */
  81. int fnp;    /* 0: do zero & markbad; 1: do format & ship; 2: do part */
  82.  
  83. {
  84.     int dev, scan=0;
  85.     char buf[512];
  86.     char sendata[56];
  87.     int partno, ret, inqret, i;
  88.     PART *partinfo;
  89.     char mask = 0x80;    /* 7th bit is set on */
  90.     int setmask;
  91.     int maxloop;
  92.  
  93.     noacsi = 1;                /* assume there is no ACSI in the system */
  94.     ostack = Super(NULL);    /* set supervice mode */
  95.  
  96.     ttscsi = chkscsi();        /* check if SCSI exists */
  97.     spscsixst = chksp();    /* check if sparrow scsi exists */
  98.     delay();
  99.     if ((atexst = chkide()))    { /* AT drive exist */
  100.         if (stbook())    {
  101.             useblit = 0;
  102.         } else {
  103.             useblit = chkblit();
  104.         }
  105.         if ((ret = identify(16, buf)) == OK)    {
  106.             delay();
  107.             /* in byte 54 of the buf having the drive's id */
  108.             gdrvid(16, &buf[54], drvid[16]);
  109.             /* return the number of cylinder, head, spt */
  110.             gparmfc(&atcyl, &athead, &atspt, buf);
  111.         } else { 
  112.             if (ret == -1)    { /* May-10-93: fix a bug by adding these codes */
  113.                 /* The bug is when Falcon without a ide drive, it will return
  114.                    a timeout, so now I will continue the process instead of 
  115.                    tread it as a error */
  116.                 drvid[16] = drvid[18];
  117.                 goto jjj;
  118.             }
  119.             delay();
  120.             Super(ostack);
  121.             ret = errcode(16);
  122.             if (tsterr(ret) != OK) 
  123.                 return ERROR;
  124.             return (-3);    /* don't have to show the alert box */
  125.         }
  126.     }
  127. jjj:
  128.     delay();
  129.     /*    Now the hardware doesn't support the slave drive, so comment it out
  130.     if ((atexst) && (slvexst = slave()))    {  AT slave drive exist 
  131.         if ((ret = identify(17, buf)) == OK)    {
  132.             atscyl = getword(buf+2);
  133.             atshead = getword(buf+6);
  134.             atsspt = getword(buf+12);
  135.             delay();
  136.         } else { 
  137.             delay();
  138.             Super(ostack);
  139.             ret = errcode(17);
  140.             if (tsterr(ret) != OK) 
  141.                 return ERROR;
  142.             return (-3);    don't have to show the alert box
  143.         }
  144.     }
  145.     */
  146.     delay();
  147.     Super(ostack);
  148.     /* set the scent message box */
  149.     if ((needscan) && ((ttscsi)||(spscsixst)))
  150.         dsplymsg(scanmsg);
  151.  
  152.     /* disable all logical and physical devs */
  153.     for (dev = 0; dev < EXTRALOGD; ++dev)
  154.         logmap[dev].lm_physdev = -1;
  155.  
  156.     for (dev = 0; dev < MAXPHYSDEVS; ++dev)
  157.         livedevs[dev] = 0;
  158.  
  159.     /* set all devices have no id */
  160.     for(i=0; i < 16; i++)    {
  161.         idevs[i] = 0;
  162.     }
  163.  
  164.     /*
  165.      * Scan all physical devs
  166.      * and pick up partition structures.
  167.      */
  168.     nlogdevs = 0;
  169.     showmany = 0;
  170.     slwacsi = 0;
  171.     if (atexst)    {
  172.         maxloop = 18;
  173.         dev = 16;
  174.     } else if ((ttscsi)||(spscsixst))    {
  175.         if (spscsixst)    {
  176.             slwacsi = 1;
  177.         } 
  178.         maxloop = 16;
  179.         dev = 8;
  180.     } else {
  181.         maxloop = 8;
  182.         slwacsi = 1;
  183.         dev = 0;
  184.     }
  185. rerescan:
  186.     for (; dev < maxloop; ++dev)
  187.     {
  188.  
  189.         if (((dev == 16) && atexst) || ((dev == 17) && slvexst))    {
  190.             if ((ret = getroot(dev, buf, (SECTOR)0)) != 0)    {
  191.                 if (ret == -1)    { /* May-10-93: to fix a bug that can't format
  192.                                      in the Falcon without a ide drive */
  193.                     /* it is timeout or without a ide drive in Falcon */
  194.                     goto noidedr;
  195.                 }
  196.                 if (tsterr(ret) != OK)    
  197.                     err(rootread);
  198.                 slwacsi = 0;
  199.                 return(ERROR);
  200.             }
  201.             goto atst;    /* skip and do the at stuff only */
  202.         }
  203.         /* initialize the buffer */
  204.         for (i = 0; i < 56; i++)        {
  205.             sendata[i] = 0;
  206.         }
  207.  
  208.         /* check see the drive is a what kind of drive */
  209.            ostack = Super(NULL);
  210.            delay();
  211.         if ((inqret = inquiry(dev, (WORD)56, sendata)) != ERROR)    {
  212.             for (i=8; i < 56; i++)    {
  213.                 if (sendata[i])    {
  214.                     break;
  215.                 }
  216.             }
  217.             if (i < 56)    {    /* there are some date return */
  218.                 gdrvid(dev, &sendata[8], drvid[dev]);
  219.                 idevs[dev] = 1;
  220.             }
  221.         }
  222.            delay();
  223.            Super(ostack);
  224.         setmask = 0x0001;
  225.         if (inqret & 0x08)    { /* the device is busy */
  226.             continue;
  227.         }
  228.         /* ret not equal OK, it may be a regular hard drive */
  229.         if ((inqret == OK)||(inqret == 7)) { /*it is not a regular hard drive*/
  230.             if (sendata[0])      {    /* it is not a hard drive */
  231.                 continue;
  232.             } else if (sendata[1] & mask)    { /* it is a removable drive */
  233.                    ostack = Super(NULL);
  234.                    delay();
  235.                 mdsense(dev, 0x2e, 0, 42, buf);    /* unlock the floptical drive */
  236.                    delay();
  237.                    Super(ostack);
  238.                 if (spscsixst)    {
  239.                       /* it is a SCSI drive */
  240.                     /* set the relative bit, 1 is a SCSI, other is not */
  241.                     typedrv |= setmask << dev;
  242.                     /* set the relative bit, 1 is a removable */
  243.                     typedev |= setmask << dev;
  244.                 } else {
  245.                     ;            /* don't set the SCSI bit */
  246.                 }
  247.             /*    Jul 15, 93 jye: consider the Mega STE which is also a use the 
  248.                 scsi drive under the acsi bus, in this case, we need set the
  249.                 'typedrv', if so, the bug that can't format the unit 0 will be
  250.                 killed. If the 'inqret' = OK, this means they drive is SCSI
  251.                 drive.
  252.             } else if (dev > 7)    {
  253.             */
  254.             } else    {
  255.                   /* it is a SCSI drive, because inqret = OK */
  256.                 /* set the relative bit, 1 is a SCSI, other is not */
  257.                 typedrv |= setmask << dev;
  258.             }
  259.         }
  260.         if ((ret = getroot(dev, buf, (SECTOR)0)) < 0) {
  261.             if (!fnp)  rangelog(dev);
  262.             continue;
  263.         } else {        /* ret >= 0 */
  264.             if (ret > 0) {
  265.                 if ((flag) && (tsterr(ret) == OK))    {    
  266.                 /* if non-0, report error if medium changed */
  267.                         erasemsg();
  268.                         /* Jul-23-93 jye: Fixed this bug that we should conti-
  269.                            nue scan the rest drives. So delet this 2 lines
  270.  
  271.                         slwacsi = 0;
  272.                          return ERROR;
  273.  
  274.                         */
  275.                         continue;
  276.                 }
  277.                 if ((ret = getroot(dev, buf, (SECTOR)0))) {    /* try again */
  278.                     if (ret > 0 && flag && tsterr(ret) == OK)    {
  279.                         erasemsg();
  280.                         /* Jul-23-93 jye: Fixed this bug that we should conti-
  281.                            nue scan the rest drives. So delet this 2 lines
  282.  
  283.                         slwacsi = 0;
  284.                          return ERROR;
  285.  
  286.                         */
  287.                         continue;
  288.                     } else if ((ret > 0) && (!flag))    {
  289.                         if (((inqret == OK)||(inqret == 7)) && 
  290.                                              (sendata[1] & mask))    { 
  291.                             /* it is a removable drive */
  292.                             /* but forget insert the cartridge */
  293.                             err(instdrv);
  294.                                ostack = Super(NULL);
  295.                                delay();
  296.                             /* unlock the floptical drive */
  297.                             mdsense(dev, 0x2e, 0, 42, buf);    
  298.                                delay();
  299.                                Super(ostack);
  300.                             /* set the relative bit, 1 is a removable */
  301.                             typedev |= setmask << dev;
  302.                         }
  303.                         /*
  304.                         if (fnp == 1)    {  do format 
  305.                             livedevs[dev] = 1;
  306.                             if (dev < 8)  there is a ACSI in the system 
  307.                                 noacsi = 0;
  308.                             yesscan = 1;
  309.                         }
  310.                         */
  311.                     }
  312.                     if (!fnp)    {
  313.                         rangelog(dev);
  314.                     }
  315.                     continue;
  316.                 }
  317.             }
  318.             if ((inqret == OK)||(inqret == 7))     {  /* it is a SCSI drive */
  319.                 if (sendata[1] & mask)    { /* it is a removable drive */
  320.                     /* set the relative bit, 1 is a removable, other is not */
  321.                     typedev |= setmask << dev;
  322.                        ostack = Super(NULL);
  323.                        delay();
  324.                     /* unlock the floptical drive */
  325.                     mdsense(dev, 0x2e, 0, 42, buf);    
  326.                        delay();
  327.                        Super(ostack);
  328.                 }
  329.             }
  330.     atst:
  331.             if (dev < 8)    {    /* there is a ACSI drive in the system */
  332.                 noacsi = 0;
  333.             }
  334.             livedevs[dev] = 1;
  335.             yesscan = 1;
  336.             if (stgpart(dev, buf, (PART *)&partinfo) == ERROR)    {
  337.                 erasemsg();
  338.                 slwacsi = 0;
  339.                 return ERROR;
  340.             }
  341.             if (ext != NO_EXT)    {
  342.                 sortpart(partinfo,SCAN_BS); 
  343.             }
  344.         for (partno = 0; partno < npart; ++partno) {
  345.             if ((partinfo[partno].p_flg & P_EXISTS) &&
  346.                 (partinfo[partno].p_siz != (SECTOR)0) &&
  347.                 (((partinfo[partno].p_id[0] == 'G') &&
  348.                  (partinfo[partno].p_id[1] == 'E') &&
  349.                  (partinfo[partno].p_id[2] == 'M'))   ||
  350.                  ((partinfo[partno].p_id[0] == 'B') &&
  351.                  (partinfo[partno].p_id[1] == 'G') &&
  352.                  (partinfo[partno].p_id[2] == 'M'))))   
  353.             {
  354.                 if (nlogdevs > EXTRALOGD)    {
  355.                     continue;
  356.                 }
  357.                 logmap[nlogdevs].lm_physdev = dev;
  358.                 logmap[nlogdevs].lm_partno = partno;
  359.                 logmap[nlogdevs].lm_start =  partinfo[partno].p_st;
  360.                 logmap[nlogdevs].lm_siz =      partinfo[partno].p_siz;
  361.                 ++nlogdevs;
  362.                 if (nlogdevs == MAXLOGDEVS)         {
  363.                     showmany = 1;
  364.                 }
  365.             }
  366.         }
  367.     }
  368.     inipart(partinfo, npart);
  369.     if (partinfo > 0)    Mfree(partinfo);
  370.     }
  371.  
  372. noidedr:
  373.     if ((maxloop > 16) && ((ttscsi)||(spscsixst)))    {
  374.         maxloop = 16;
  375.         dev = 8;
  376.         slwacsi = 0;
  377.         if (spscsixst)    {
  378.             slwacsi = 1;
  379.         }
  380.         goto rerescan;
  381.     } else if (((maxloop > 16) && ((!ttscsi)&&(!spscsixst))) 
  382.                                || ((ttscsi)&&(maxloop>8)))    {
  383.         maxloop = 8;
  384.         dev = 0;
  385.         slwacsi = 1;
  386.         goto rerescan;
  387.     }
  388.     erasemsg();
  389.     slwacsi = 0;
  390.     return OK;
  391. }
  392.  
  393.  
  394.  
  395. /* get the identification of drive */
  396.  
  397. gdrvid(indx, sptr, dptr)
  398. int indx;
  399. char *sptr;
  400. char *dptr;
  401. {
  402.  
  403.     int i, j=0;
  404.  
  405.     /* string in ptr is sperated by space */
  406.     for (i=0; i < 24; i++)    {
  407.         if ((*dptr++ = *sptr++) == 0x20)    {
  408.             j++;
  409.             if (j > 1)    {
  410.                 dptr--;
  411.             }
  412.         } else {
  413.             j = 0;
  414.         }
  415.     }
  416.     *(dptr-1) = 0;
  417.     /*
  418.     while ((*sptr != 0x20) && (*sptr))    {
  419.         *dptr++ = *sptr++;
  420.     }
  421.     *dptr++ = 0x20;
  422.     sptr = ptr+8;
  423.     while ((*sptr != 0x20) && (*sptr))    {
  424.         *dptr++ = *sptr++;
  425.     }
  426.     *dptr = 0;
  427.     */
  428. }
  429.  
  430.  
  431. /* rerange the partition informations. */
  432.  
  433.  sortpart(pinfo, type)
  434.  PART *pinfo;
  435.  int type;                /* USER_ED = 1: for user interface use */
  436.                          /* SCAN_BS = 0: for rescan() and laybs() use */
  437.  {
  438.      int i, j, k;
  439.     PART rpart[2];
  440.  
  441.     if (ext == NO_EXT) return OK;    /* don't need sort */
  442.     for (i = 0; i < 2; i++)    { /* initialize the temple space */
  443.         rpart[i].p_flg = 0L;
  444.         rpart[i].p_st = 0L;
  445.         rpart[i].p_siz = 0L;
  446.         for (k = 0; k < 3; k++)
  447.             rpart[i].p_id[k] = '0';
  448.     }
  449.     /* save the partitions that after the extened partitions */
  450.     for (i = ext+1, j=0; i < 4; i++, j++)        {
  451.         if (pinfo[i].p_flg & P_EXISTS)    {
  452.             rpart[j].p_flg = P_EXISTS;
  453.             rpart[j].p_st = pinfo[i].p_st;
  454.             rpart[j].p_siz = pinfo[i].p_siz;
  455.             for (k = 0; k < 3; k++)
  456.                 rpart[j].p_id[k] = pinfo[i].p_id[k];
  457.         } 
  458.     }
  459.     /* move the extened partition to the front */
  460.      for (i=4, j = ext; i < npart; i++, j++)    {
  461.         if (pinfo[i].p_flg & P_EXISTS)    {
  462.             pinfo[j].p_flg = P_EXISTS;
  463.             pinfo[j].p_st = (type)?(pinfo[i].p_st):(pinfo[i].p_st + ROOTSECT);
  464.             pinfo[j].p_siz = (type)?(pinfo[i].p_siz):(pinfo[i].p_siz-ROOTSECT);
  465.             for (k = 0; k < 3; k++)
  466.                 pinfo[j].p_id[k] = pinfo[i].p_id[k];
  467.         } else { j--;}    /* stay with that space */
  468.     }
  469.     /* copy the not extended partitions back after the extended partitions */
  470.      for (i=0; i < 2; i++, j++)    {
  471.         if (rpart[i].p_flg & P_EXISTS)    {
  472.             pinfo[j].p_flg = P_EXISTS;
  473.             pinfo[j].p_st = rpart[i].p_st;
  474.             pinfo[j].p_siz = rpart[i].p_siz;
  475.             for (k = 0; k < 3; k++)
  476.                 pinfo[j].p_id[k] = rpart[i].p_id[k];
  477.         } else {j--;}
  478.     }
  479.     for (i = j; i < npart; i++)    { /* set the rest to 0 */
  480.         pinfo[i].p_flg = 0L;
  481.         pinfo[i].p_st = 0L;
  482.         pinfo[i].p_siz = 0L;
  483.         for (k = 0; k < 3; k++)
  484.             pinfo[i].p_id[k] = '0';
  485.     }
  486. }
  487.  
  488.  
  489. /* 
  490.  * check to find out the exist of device
  491.  */
  492.  
  493. rangelog(dev)
  494.  
  495. int dev;
  496.  
  497. {
  498.     PUNINFO *divinfo;
  499.     int devnum;
  500.  
  501.     ostack = Super(NULL);
  502.     divinfo = ((PUNINFO *) *((long *)(0x516)));
  503.     for (devnum = 0; devnum < MAXUNITS; ++devnum)    {
  504.         if ((int)(divinfo->pun[devnum] & 0x07) == dev)    {
  505.             delay();
  506.             nlogdevs++;
  507.         }
  508.     }
  509.     Super(ostack);
  510. }
  511.  
  512. /*
  513.  * From a PHYSICAL device unit (0->7)
  514.  * and a partition number (0->3), figure
  515.  * out the LOGICAL disk number ('C'->'P').
  516.  *
  517.  * return the LOGICAL disk number or
  518.  * ERROR if the PHYSICAL device doesn't exist.
  519.  *
  520.  */
  521. phys2log(pdev, pno)
  522. int  pdev;    /* physical device unit */
  523. int  pno;    /* partition number (0 -> 3) */
  524. {
  525.     int logdev;        /* index to step through partitions of a phys unit */
  526.  
  527.     for (logdev = 0; logdev < EXTRALOGD; logdev++) {
  528.         if (logmap[logdev].lm_physdev == pdev &&
  529.             logmap[logdev].lm_partno == pno)
  530.             return ('C'+logdev);
  531.     }
  532.     return ERROR;
  533. }
  534.  
  535.  
  536. /*
  537.  * Map block on logical device to
  538.  * block on physical device;
  539.  * return ERROR if the logical device
  540.  * doesn't exist.
  541.  */
  542. log2phys(adev, ablk)
  543. int *adev;
  544. SECTOR *ablk;
  545. {
  546.     int dev;
  547.     char xbuf[256];
  548.     
  549.     dev = *adev;
  550.     if (dev >= 0 && dev <= 17)
  551.     return OK;
  552.  
  553.     dev = toupper(dev);
  554.     if (dev >= 'C' && dev <= 
  555.                 ('C'+EXTRALOGD)) /* from C to 't' are 50 logic device */
  556.     {
  557.     dev -= 'C';
  558.     *adev = logmap[dev].lm_physdev;
  559.     *ablk = logmap[dev].lm_start + *ablk;
  560.     return OK;
  561.     }
  562.  
  563.     return ERROR;
  564. }
  565.  
  566.  
  567.  
  568. /*
  569.  * Return physical starting block# of a partition
  570.  *
  571.  */
  572. SECTOR 
  573. logstart(ldev)
  574. int ldev;    /* logical device */
  575. {
  576.     ldev = toupper(ldev);
  577.     if (ldev >= 'C' && ldev <= 
  578.                 ('C'+EXTRALOGD)){/*from C to 't' are 50 logic device */
  579.         ldev -= 'C';
  580.         return (logmap[ldev].lm_start);
  581.     }
  582.     return ERROR;
  583. }
  584.  
  585.  
  586.  
  587. /*
  588.  * Return physical starting block# of a partition's data block.
  589.  *
  590.  */
  591. SECTOR 
  592. logend(ldev)
  593. int ldev;    /* logical device */
  594. {
  595.     ldev = toupper(ldev);
  596.     if (ldev >= 'C' && ldev <= 
  597.                 ('C'+EXTRALOGD)){/*from C to 't' are 50 logic device */
  598.         ldev -= 'C';
  599.         return (logmap[ldev].lm_start+logmap[ldev].lm_siz-1);
  600.     }
  601.     return ERROR;
  602. }
  603.  
  604.  
  605. #define    MFM 17        /* sectors per track for MFM */
  606. #define    RLL 26        /* sectors per track for RLL */
  607.  
  608.  
  609. /*
  610.  * Check if dev's root block is intact.
  611.  * Return number of sectors per track on disk.
  612.  *
  613.  */
  614. chkroot(dev, bs)
  615. int dev;
  616. char *bs;
  617. {
  618.     extern long get3bytes();
  619.     extern long get4bytes();
  620.     SETMODE *mb;
  621.     int i, ret, set, scsidrv, mask=0x0001;
  622.     int page=4, bsiz;
  623.     int head, spt;
  624.     SECTOR size, msiz, cyl;    /* size of media */
  625.     char buf[512], sendata[32];
  626.     long dmaptr, tmpptr;
  627.     char *dmahigh=0xffff8609,
  628.          *dmamid=0xffff860b,
  629.          *dmalow=0xffff860d;
  630.     
  631.     size = ((RSECT *)(bs + 0x200 - sizeof(RSECT)))->hd_siz;
  632.     
  633.     ret = OK;
  634.     if (dev == 16)    {        /* it is a IDE-AT drive */
  635.         msiz = (SECTOR)athead * (SECTOR)atcyl * (SECTOR)atspt;
  636.         if (size != msiz)
  637.             ret = ERROR;
  638.         return(ret);
  639.     } else if (dev > 7)    {    /* it is a scsi drive */
  640.         ostack = Super(NULL);
  641.         delay();
  642.         if ((ret = readcap(dev, 0, (long)0, sendata)) == OK) {
  643.             if (msiz = get4bytes(sendata))    {
  644.                 msiz += 1;
  645.                 delay();
  646.                 Super(ostack);
  647.                 goto chkend;
  648.             } 
  649.         } 
  650.         for (i = 0; i < 32; i++)
  651.             sendata[i] = 0;
  652.         if ((ret = mdsense(dev, 4, 0, 32, sendata)) == OK)    {
  653.             if((msiz=get3bytes(sendata+5)))    {
  654.                         delay();
  655.                         Super(ostack);
  656.                         goto chkend;
  657.             }
  658.         }
  659.         for (i = 0; i < 32; i++)
  660.             sendata[i] = 0;
  661.         if ((ret = mdsense(dev, 0, 0, 16, sendata)) == OK)    {
  662.             if((msiz=get3bytes(sendata+5)))    {
  663.                         delay();
  664.                         Super(ostack);
  665.                         goto chkend;
  666.             }
  667.         }
  668.         for (i = 0; i < 32; i++)
  669.             sendata[i] = 0;
  670.         if ((ret = mdsense(dev, 3, 0, 32, sendata)) == OK)    {
  671.             if((msiz=get3bytes(sendata+5)))    {
  672.                         delay();
  673.                         Super(ostack);
  674.                         goto chkend;
  675.             }
  676.         }
  677.         msiz = size;
  678.         delay();
  679.         Super(ostack);
  680.         goto chkerr;
  681.     }
  682.  
  683.     ostack = Super(NULL);
  684.     /* Get format parameters/ disk size from media */
  685.     set = typedev & (mask << dev);
  686.     scsidrv = typedrv & (mask << dev);
  687.     bsiz = ((set) || (scsidrv)) ? (16) : (22);
  688.     if ((set) || (scsidrv))    {
  689.         for (i = 0; i < 32; i++)
  690.             sendata[i] = 0;
  691.         mdsense(dev, 0, 0, bsiz, sendata);
  692.         if((msiz=get3bytes(sendata+5)))    {
  693.                     delay();
  694.                     Super(ostack);
  695.                     goto chkend;
  696.         }
  697. redopg:
  698.         for (i = 0; i < 32; i++)
  699.             sendata[i] = 0;
  700.         ret = mdsense(dev, page, 0, 32, sendata);/* use page code 4, but get */
  701.                                             /* info from the mdsense header */
  702.         for (i = 0; i < 32; i++)
  703.             if (sendata[i])
  704.                 break;
  705.         if ((i==32) && (page == 4))        {
  706.             page = 3;
  707.             goto redopg;
  708.         } else if (i == 32)    {
  709.             msiz = size;
  710.             delay();
  711.             Super(ostack);
  712.             goto chkend;
  713.         }
  714.         if (!(msiz = get3bytes(sendata+5)))    {
  715.             if (page == 4)    {
  716.                 page = 3;
  717.                 /*
  718.                 cyl = get3bytes(sendata+14);
  719.                 head = *(sendata+17);
  720.                 */
  721.                 goto redopg;
  722.             } else {
  723.                 /*
  724.                 spt = getword(sendata+22);
  725.                 msiz = cyl * head * spt;
  726.                 */
  727.                 msiz = size;
  728.             }
  729.         }
  730.         delay();
  731.         Super(ostack);
  732.         goto chkend;
  733.     } else    {
  734.         ret = mdsense(dev, 0, 0, 22, sendata);
  735.         delay();
  736.         Super(ostack);
  737.  
  738.         /* If full SCSI, will return number of blocks */
  739.         /* on disk at byte 5, 6 and 7.  If Adaptec,   */
  740.         /* will return 0 for number of blocks on disk */
  741.         /* on SCSI. */
  742.  
  743.             if (!(msiz = get3bytes(sendata+5))) {    /* no disk size returned? */
  744.             /* Yup, ie., it's adaptec's.  Interpret as SETMODE structure */
  745.             mb = (SETMODE *)sendata;
  746.             /* get number of cylinders */
  747.             cyl = mb->smd_cc[0];
  748.             cyl <<= 8;
  749.             cyl |= mb->smd_cc[1];
  750.     
  751.             /* get number of heads */
  752.             head = mb->smd_dhc;
  753.     
  754.             msiz = (SECTOR)head * (SECTOR)cyl * MFM;
  755.     
  756.             for (i = 0; i < 20; i++) {
  757.                 if ((ret = rdsects(dev, 1, buf, msiz+i)) == OK) {
  758.                     /* find out whether data has been transferred, by
  759.                           checking if dma pointer has been moved.      */
  760.  
  761.                     ostack = Super(NULL);
  762.                     delay();
  763.                     dmaptr = *dmahigh;
  764.                     dmaptr &= 0x0000003f;
  765.                     dmaptr <<= 16;
  766.                     tmpptr = *dmamid;
  767.                     tmpptr &= 0x000000ff;
  768.                     tmpptr <<= 8;
  769.                     dmaptr |= tmpptr;
  770.                     tmpptr = *dmalow;
  771.                     tmpptr &= 0x000000ff;
  772.                     dmaptr |= tmpptr;
  773.                     delay();
  774.                     Super(ostack);
  775.  
  776.                     if (dmaptr != buf)
  777.                         break;
  778.                    } else {            /* rdsects return an error */
  779.                     if (tsterr(ret) == OK) {
  780.                            break;
  781.                     }
  782.                 }
  783.             }
  784.     
  785.             if (ret == MDMCHGD)        /* check if error occurred */
  786.                 return (ret);
  787.        
  788.             /* Determine if media is MFM or RLL */
  789.             if (i < 20)    {
  790.                 msiz = (SECTOR)head * (SECTOR)cyl * RLL;
  791.             }
  792.             goto chkend;
  793.         }
  794.     }
  795. chkerr:
  796.     if (ret != 0) {
  797.         ret = errcode(dev);
  798.         if (tsterr(ret) != OK) 
  799.             return ERROR;
  800.         return (-3);    /* don't have to show the alert box */
  801.     }
  802. chkend:
  803.     if (size != msiz)
  804.         ret = ERROR;
  805.     else 
  806.         ret = OK;
  807.         
  808.     return (ret);
  809. }
  810.  
  811. /*
  812.  * Chkparm()
  813.  *    Check if given logical device has the asssumed parameters.
  814.  * Assumptions are:
  815.  *    - 512 bytes/sector
  816.  *    - 2 sectors/cluster
  817.  *    - 1 reserved sector
  818.  *    - 2 FATs
  819.  *
  820.  * Input:
  821.  *    ldev - logical device number ('C' -> 'P').
  822.  *
  823.  * Return:
  824.  *    OK - parameters of partition match the assumptions
  825.  *    ERROR - something went wrong.
  826.  *
  827.  * Comment:
  828.  *    Number of FATs is assumed to be 2.  Cannot check this 
  829.  * because previous version of HDX did not put that in the boot
  830.  * sector.
  831.  */
  832. chkparm(ldev)
  833. int ldev;
  834. {
  835.     char bs[512];        /* boot sector */
  836.     BOOT *boot;            /* boot structure */
  837.     UWORD bps, res, siz;    /* bytes/sector, num reserved sectors, ldev size */
  838.     int ret;
  839.  
  840.     if ((ret = rdsects(ldev, 1, bs, (SECTOR)0)) != 0) {
  841.         if (tsterr(ret) != OK)
  842.             err(bootread);
  843.         ret = ERROR;
  844.         goto parmend;
  845.     }    
  846.  
  847.     boot = (BOOT *)bs;
  848.     gw((UWORD *)&boot->b_bps, &bps);    /* what is number bytes/sector? */
  849.     gw((UWORD *)&boot->b_res, &res);    /* what is num of reserved sectors? */
  850.     gw((UWORD *)&boot->b_nsects, &siz);    /* what is size of partition */
  851.     if (bps % BPS            /* bytes per sector == ratio of 512 ? */
  852.     || res != 1) {            /* num sectors reserved == 1 ? */
  853.     ret = ERROR;            /* Nope, different from assumptions */
  854.     goto parmend;
  855.     }
  856.     
  857.     /* Check if sectors per cluster make sense */
  858.     if (boot->b_spc != 2) {
  859.         ret = ERROR;
  860.         goto parmend;
  861.     }
  862.     
  863.     ret = OK;                /* If yes, return OK */
  864.  
  865. parmend:
  866.     return ret;
  867. }
  868.  
  869.  
  870. ichkparm(ldev)
  871. int ldev;
  872. {
  873.     char bs[512];        /* boot sector */
  874.     BOOT *boot;            /* boot structure */
  875.     UWORD bps, res, siz;    /* bytes/sector, num reserved sectors, ldev size */
  876.     int ret;
  877.  
  878.     if ((ret = rdsects(ldev, 1, bs, (SECTOR)0)) != 0) {
  879.         if (tsterr(ret) != OK)
  880.             err(bootread);
  881.         ret = ERROR;
  882.         goto parmend;
  883.     }    
  884.  
  885.     boot = (BOOT *)bs;
  886.     gw((UWORD *)&boot->b_bps, &bps);    /* what is number bytes/sector? */
  887.     gw((UWORD *)&boot->b_res, &res);    /* what is num of reserved sectors? */
  888.     gw((UWORD *)&boot->b_nsects, &siz);    /* what is size of partition */
  889.     if (bps != 512            /* bytes per sector == 512 ? */
  890.     || res != 1) {            /* num sectors reserved == 1 ? */
  891.     ret = ERROR;            /* Nope, different from assumptions */
  892.     goto parmend;
  893.     }
  894.     
  895.     /* Check if sectors per cluster make sense */
  896.     if ((siz >= 0x8000L && boot->b_spc != 4) ||
  897.         (siz < 0x8000L && boot->b_spc != 2)) {
  898.         ret = ERROR;
  899.         goto parmend;
  900.     }
  901.     
  902.     ret = OK;                /* If yes, return OK */
  903.  
  904. parmend:
  905.     return ret;
  906. }
  907.  
  908.  
  909. /*
  910.  * Get dev's root block.
  911.  *
  912.  */
  913. getroot(dev, buf, sect)
  914. int dev;
  915. char *buf;
  916. SECTOR sect;
  917. {
  918.     return rdsects(dev, 1, buf, sect);
  919. }
  920.  
  921.  
  922. /*
  923.  * Put dev's root block.
  924.  *
  925.  */
  926. putroot(dev, buf, sect)
  927. int dev;
  928. char *buf;
  929. SECTOR sect;
  930. {
  931.     return wrsects(dev, 1, buf, sect);
  932. }
  933.  
  934.  
  935. /*
  936.  *  Read sector(s) from dev.
  937.  *
  938.  *  Input:
  939.  *    dev - device number (logical or physical).
  940.  *    num - number of sectors to read.
  941.  *    buf - buffer to write data read.
  942.  *    sect - starting sector number to read from.
  943.  *
  944.  *  Return:
  945.  *    errnum - 0: if read is successful.
  946.  *         an error code: if read is unsuccessful.
  947.  */
  948. rdsects(dev, num, buf, sect)
  949. int dev;            /* device number (logical or physical) */
  950. UWORD num;            /* number of sectors to read */
  951. char *buf;
  952. SECTOR sect;            /* starting sector to read from */
  953. {
  954.     int errnum;
  955.  
  956.     if (log2phys(&dev, §) < 0)
  957.     return ERROR;
  958.  
  959.     ostack = Super(NULL);
  960.     if (dev == 16)    { /* it is a AT drive */
  961.         /*
  962.         if (!(athead*atspt*sect))    {
  963.             formaterr(dev);
  964.             errnum = ERROR;
  965.         } else {
  966.             errnum = ideread(athead, atspt, sect, num, buf, (UWORD)dev);
  967.         }
  968.         */
  969.         errnum = ideread(athead, atspt, sect, num, buf, (UWORD)dev);
  970.     } else {
  971.         /*
  972.         if (spscsixst)    {
  973.             resetspscsi();
  974.         }
  975.         */
  976.         errnum = hread(sect, num, buf, (UWORD)dev);
  977.     }
  978.     /*
  979.     if (errnum == 04)    {      the drive is stop 
  980.         delay();
  981.         stunt();
  982.         delay();
  983.         errnum = hread(sect, num, buf, (UWORD)dev);
  984.     }
  985.     */
  986.     delay();
  987.     Super(ostack);
  988.  
  989.     if (errnum > 0) {
  990.         errnum = errcode(dev);
  991.     }
  992.         
  993.     return errnum;        /* return the error code */
  994. }
  995.  
  996.  
  997. /*
  998.  *  Write sector(s) to dev.
  999.  *
  1000.  *  Input:
  1001.  *    dev - device number (logical or physical).
  1002.  *    num - number of sectors to write.
  1003.  *    buf - buffer with data to be written.
  1004.  *    sect - starting sector number to write to.
  1005.  *
  1006.  *  Return:
  1007.  *    errnum - 0: if write is successful.
  1008.  *         an error code: if write is unsuccessful.
  1009.  */
  1010. wrsects(dev, num, buf, sect)
  1011. int dev;            /* device number (logical or physical */
  1012. UWORD num;            /* number of sectors to write */
  1013. char *buf;            /* buffer with data to be written */
  1014. SECTOR sect;            /* starting sector to write to */
  1015. {
  1016.     int errnum;
  1017.  
  1018.     if (log2phys(&dev, §) < 0)
  1019.     return ERROR;
  1020.  
  1021.     ostack = Super(NULL);
  1022.     if (dev == 16)    { /* it is a AT drive */
  1023.         /*
  1024.         if (!(athead*atspt*sect))    {
  1025.             formaterr(dev);
  1026.             errnum = ERROR;
  1027.         } else {
  1028.             errnum = idewrite(athead, atspt, sect, num, buf, (UWORD)dev);
  1029.         }
  1030.         */
  1031.         errnum = idewrite(athead, atspt, sect, num, buf, (UWORD)dev);
  1032.     } else {
  1033.         errnum = hwrite(sect, num, buf, (UWORD)dev);
  1034.     }
  1035.     delay();
  1036.     Super(ostack);
  1037.  
  1038.     if (errnum > 0) {
  1039.         errnum = errcode(dev);
  1040.     }
  1041.     return errnum;
  1042. }
  1043.  
  1044.  
  1045. /*
  1046.  * Zero range of sectors on dev.
  1047.  *
  1048.  */
  1049. zerosect(dev, start, count)
  1050. int dev;
  1051. SECTOR start;
  1052. UWORD count;
  1053. {
  1054.     char *zbuf;
  1055.     int  v;
  1056.     UWORD i;
  1057.  
  1058.     if ((zbuf = (char *)mymalloc(ZBUFSIZ)) <= 0)
  1059.         return err(nomemory);
  1060.         
  1061.     if (log2phys(&dev, &start) < 0) {
  1062.         free(zbuf);
  1063.     return ERROR;
  1064.     }
  1065.  
  1066.     fillbuf(zbuf, (long)ZBUFSIZ, 0L);
  1067.  
  1068.     while (count)
  1069.     {
  1070.         if (count > ZCOUNT)
  1071.             i = ZCOUNT;
  1072.         else i = count;
  1073.  
  1074.     if ((v = wrsects(dev, i, zbuf, start)) != 0)
  1075.         break;
  1076.     start += i;
  1077.     count -= i;
  1078.     }
  1079.     free(zbuf);
  1080.     
  1081.     return v;
  1082. }
  1083.