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 ---