Hi!

- bugfix: Genblkdev():
  - formatting loop (0x42 function) rewritten: instead formating many tracks,
    was formated one track many times (because afentry.head++ outside loop);
  - now checked "afentry.track >= pddt->ddt_ncyl" (instead ">");
  - now gbfv_spcfunbit cleared at <exit when bit 0 is set>;
  - not fixed: there remained two returns without setting gbfv_spcfunbit;
  - verification (0x62) now check only bit 0 of gbfv_spcfunbit;
  - not fixed: verification should set gbfv_spcfunbit in case of errors.

- many variables (like `ret') moved deeply (by adding curly braces) - for
  BC this noticeably decreases stack usage.

--- Begin Message ---
diff -ruNp old/kernel/dsk.c new/kernel/dsk.c
--- old/kernel/dsk.c    2004-06-11 03:38:38.000000000 +0000
+++ new/kernel/dsk.c    2004-06-11 04:03:14.000000000 +0000
@@ -526,52 +526,42 @@ STATIC WORD Genblkdev(rqptr rp, ddt * pd
     case 0x42:                 /* format/verify track */
       {
         struct gblkfv FAR *fv = rp->r_fv;
-        COUNT tracks;
-        struct thst {
-          UBYTE track, head, sector, type;
-        } *addrfield, afentry;
+        int ret;
 
         pddt->ddt_descflags &= ~DF_DPCHANGED;
         if (hd(descflags))
         {
           /* XXX no low-level formatting for hard disks implemented */
-          fv->gbfv_spcfunbit = 1;       /* "not supported by bios" */
-          return S_DONE;
+          fv->gbfv_spcfunbit = 1; /* "not supported by bios" */
+          break;
         }
-        if (descflags & DF_DPCHANGED)
+
+        /* first try newer setmediatype function */
+        if ((descflags & DF_DPCHANGED) &&
+            (ret = fl_setmediatype(pddt->ddt_driveno, pddt->ddt_ncyl,
+                                   pddt->ddt_bpb.bpb_nsecs)) != 0)
         {
-          /* first try newer setmediatype function */
-          ret = fl_setmediatype(pddt->ddt_driveno, pddt->ddt_ncyl,
-                                pddt->ddt_bpb.bpb_nsecs);
           if (ret == 0xc)
           {
             /* specified tracks, sectors/track not allowed for drive */
             fv->gbfv_spcfunbit = 2;
-            return dskerr(ret);
+            return failure(E_NOTFND); /*dskerr(0xc)*/
           }
-          else if (ret == 0x80)
+          if (ret == 0x80 ||
+              (fv->gbfv_spcfunbit & 1) &&
+               (ret = fl_read(pddt->ddt_driveno, 0, 0, 1, 1,
+                              DiskTransferBuffer)) != 0)
           {
-            fv->gbfv_spcfunbit = 3;     /* no disk in drive */
+            fv->gbfv_spcfunbit = 3; /* no disk in drive */
             return dskerr(ret);
           }
-          else if (ret != 0)
-            /* otherwise, setdisktype */
+          /* otherwise, setdisktype */
           {
-            unsigned char type;
-            unsigned tracks, secs;
-            if ((fv->gbfv_spcfunbit & 1) &&
-                (ret =
-                 fl_read(pddt->ddt_driveno, 0, 0, 1, 1,
-                         DiskTransferBuffer)) != 0)
-            {
-              fv->gbfv_spcfunbit = 3;   /* no disk in drive */
-              return dskerr(ret);
-            }
             /* type 1: 320/360K disk in 360K drive */
             /* type 2: 320/360K disk in 1.2M drive */
-            tracks = pddt->ddt_ncyl;
-            secs = pddt->ddt_bpb.bpb_nsecs;
-            type = pddt->ddt_type + 1;
+            unsigned tracks = pddt->ddt_ncyl;
+            unsigned secs = pddt->ddt_bpb.bpb_nsecs;
+            UBYTE type = pddt->ddt_type + 1;
             if (!(tracks == 40 && (secs == 9 || secs == 8) && type < 3))
             {
               /* type 3: 1.2M disk in 1.2M drive */
@@ -584,60 +574,79 @@ STATIC WORD Genblkdev(rqptr rp, ddt * pd
               {
                 /* specified tracks, sectors/track not allowed for drive */
                 fv->gbfv_spcfunbit = 2;
-                return dskerr(0xc);
+                return failure(E_NOTFND); /*dskerr(0xc)*/
               }
             }
             fl_setdisktype(pddt->ddt_driveno, type);
           }
         }
         if (fv->gbfv_spcfunbit & 1)
-          return S_DONE;
-
-        afentry.type = 2;       /* 512 byte sectors */
-        afentry.track = fv->gbfv_cyl;
-        afentry.head = fv->gbfv_head;
-
-        for (tracks = fv->gbfv_spcfunbit & 2 ? fv->gbfv_ntracks : 1;
-             tracks > 0; tracks--)
         {
-          addrfield = (struct thst *)DiskTransferBuffer;
-
-          if (afentry.track > pddt->ddt_ncyl)
-            return failure(E_FAILURE);
-
-          for (afentry.sector = 1;
-               afentry.sector <= pddt->ddt_bpb.bpb_nsecs; afentry.sector++)
-            memcpy(addrfield++, &afentry, sizeof(afentry));
-
-          ret =
-              Genblockio(pddt, LBA_FORMAT, afentry.head, afentry.track, 0,
-                         pddt->ddt_bpb.bpb_nsecs, DiskTransferBuffer);
-          if (ret != 0)
-            return dskerr(ret);
+          fv->gbfv_spcfunbit = 0; /* success */
+          break;
         }
-        afentry.head++;
-        if (afentry.head >= pddt->ddt_bpb.bpb_nheads)
+
         {
-          afentry.head = 0;
-          afentry.track++;
+          unsigned cyl = fv->gbfv_cyl;
+          unsigned head = fv->gbfv_head;
+          unsigned tracks = fv->gbfv_spcfunbit & 2 ? fv->gbfv_ntracks : 1;
+
+          for (; tracks; tracks--)
+          {
+            if (cyl >= pddt->ddt_ncyl)         /* ??? remove --avb */
+              return failure(E_FAILURE);
+            {
+              struct thst {
+                UBYTE cyl, head, sector, type;
+              } *addrfield = (struct thst *)DiskTransferBuffer;
+              unsigned sector = 0;
+              do
+              {
+                sector++;
+                addrfield->type = 2; /* 512 byte sectors */
+                addrfield->cyl = cyl;
+                addrfield->head = head;
+                addrfield->sector = sector;
+                addrfield++;
+              } while (sector < pddt->ddt_bpb.bpb_nsecs);
+            }
+            {
+              int ret = Genblockio(pddt, LBA_FORMAT, head, cyl, 0,
+                                   pddt->ddt_bpb.bpb_nsecs, DiskTransferBuffer);
+              if (ret)
+                return ret;
+            }
+            if (++head >= pddt->ddt_bpb.bpb_nheads)
+            {
+              head = 0;
+              cyl++;
+            }
+          }
         }
-      }
 
+        fv->gbfv_spcfunbit >>= 1; /* move bit 1 to bit 0 */
+      }
       /* fall through to verify */
 
     case 0x62:                 /* verify track */
       {
         struct gblkfv FAR *fv = rp->r_fv;
-
-        ret = Genblockio(pddt, LBA_VERIFY, fv->gbfv_head, fv->gbfv_cyl, 0,
-                         (fv->gbfv_spcfunbit ?
-                          fv->gbfv_ntracks * pddt->ddt_defbpb.bpb_nsecs :
-                          pddt->ddt_defbpb.bpb_nsecs), DiskTransferBuffer);
-        if (ret != 0)
+        int ret = Genblockio(pddt, LBA_VERIFY, fv->gbfv_head, fv->gbfv_cyl, 0,
+                             (fv->gbfv_spcfunbit & 1)
+                              ? fv->gbfv_ntracks * pddt->ddt_defbpb.bpb_nsecs
+                              :                    pddt->ddt_defbpb.bpb_nsecs,
+                             DiskTransferBuffer);
+        /* !!! ret should be analyzed to fill fv->gbfv_spcfunbit by
+           1=function not supported by BIOS
+           2=specified tracks, sector/track not allowed for drive
+           3=no disk in drive
+           --avb
+        */
+        if (ret)
           return dskerr(ret);
         fv->gbfv_spcfunbit = 0; /* success */
+        break;
       }
-      break;
     case 0x46:                 /* set volume serial number */
       {
         struct Gioc_media FAR *gioc = rp->r_gioc;

--- End Message ---

Reply via email to