Hello,

First, I'd like to express my gratitude to Alain Mouette for his generous donation of an external 100 MB parallel ZIP drive + disks to me which allowed me to catch the bug below. Thank you, Alain!

Attached is the file CVSPATCH.TXT - a cumulative patch for the unstable branch that contains a fix for a bug in IOCTL.C which prevented the ZIP drive serial number to be seen. The problem was that the r_unit field was incorrectly set to unit number, whereas it must be set to subunit number. And while I was at it, I also added assignments of the SI and DI fields for IOCTL 13h/19h, because the IBM PC DOS Techical Update explicitly states that these fields contain SI/DI on pages 104 and 105.

Needless to say that I also updated CVSPATCH.TXT and KERNEL.SYS at http://linux.tu-varna.acad.bg/~lig/freedos/kernel/

Sorry for the relatively big attachment that contains patches that were already known, but Opera screws up copied-and-pasted chunks of code so attaching the patch file is the only cure for this.

Regards,
Lucho
diff -Naur cvs/kernel/hdr/device.h src/kernel/hdr/device.h
--- cvs/kernel/hdr/device.h     2004-07-24 19:02:42.000000000 +0200
+++ src/kernel/hdr/device.h     2004-08-16 10:30:12.000000000 +0200
@@ -374,7 +374,8 @@
     struct {
       UBYTE _r_cat;             /* Category code */
       UBYTE _r_fun;             /* Function code */
-      UBYTE unused[4];          /* SI or DI contents or DS:reqhdr */
+      UWORD _r_si;              /* Contents of SI and DI */
+      UWORD _r_di;              /* (PC DOS 7 Technical Update, pp 104,105) */
       union
       {
         struct gblkio FAR *_r_io;
@@ -424,6 +425,8 @@
 /* generic IOCTL and IOCTL query macros */
 #define r_cat           _r_x._r_gen._r_cat
 #define r_fun           _r_x._r_gen._r_fun
+#define r_si            _r_x._r_gen._r_si
+#define r_di            _r_x._r_gen._r_di
 #define r_rw            _r_x._r_gen._r_par._r_rw
 #define r_io            _r_x._r_gen._r_par._r_io
 #define r_fv            _r_x._r_gen._r_par._r_fv
diff -Naur cvs/kernel/kernel/inthndlr.c src/kernel/kernel/inthndlr.c
--- cvs/kernel/kernel/inthndlr.c        2004-07-25 20:12:50.000000000 +0200
+++ src/kernel/kernel/inthndlr.c        2004-08-13 12:05:56.000000000 +0200
@@ -698,10 +698,8 @@
     case 0x30:
       lr.AL = os_setver_major;
       lr.AH = os_setver_minor;
-      lr.BH = OEM_ID;
-      lr.CH = REVISION_MAJOR;   /* JPP */
-      lr.CL = REVISION_MINOR;
-      lr.BL = REVISION_SEQ;
+      lr.BX = (OEM_ID << 8) | REVISION_SEQ;
+      lr.CX = 0; /* serial number must be 0 or buggy 32RTM thrashes stack! */
 
       if (ReturnAnyDosVersionExpected)
       {
diff -Naur cvs/kernel/kernel/ioctl.c src/kernel/kernel/ioctl.c
--- cvs/kernel/kernel/ioctl.c   2004-07-24 19:02:42.000000000 +0200
+++ src/kernel/kernel/ioctl.c   2004-08-16 12:39:48.000000000 +0200
@@ -92,8 +92,9 @@
 
   sft FAR *s;
   struct dhdr FAR *dev;
+  struct dpb FAR *dpbp;
   unsigned attr, flags;
-  UBYTE cmd;
+  UBYTE cmd, unit;
 
   switch (r->AL)
   {
@@ -141,8 +142,6 @@
     case 0x0e:
     case 0x0f:
     case 0x11:
-    {
-      struct dpb FAR *dpbp;
 /*
    Line below previously returned the deviceheader at r->bl. But,
    DOS numbers its drives starting at 1, not 0. A=1, B=2, and so
@@ -154,25 +153,23 @@
 #define NDN_HACK
 #ifdef NDN_HACK
 /* NDN feeds the actual ASCII drive letter to this function */
-      UBYTE unit = (r->BL & 0x1f) - 1;
+    unit = (r->BL & 0x1f) - 1;
 #else
-      UBYTE unit = r->BL - 1;
+    unit = r->BL - 1;
 #endif
-      if (unit == 0xff)
-          unit = default_drive;
-      CharReqHdr.r_unit = unit;
-
-      if ((dpbp = get_dpb(unit)) == NULL)
-      {
-        if (r->AL != 0x09)
-          return DE_INVLDDRV;
-        attr = ATTR_REMOTE;
-      }
-      else
-      {
-        dev = dpbp->dpb_device;
-        attr = dev->dh_attr;
-      }
+    if (unit == 0xff)
+      unit = default_drive;
+
+    if ((dpbp = get_dpb(unit)) == NULL)
+    {
+      if (r->AL != 0x09)
+        return DE_INVLDDRV;
+      attr = ATTR_REMOTE;
+    }
+    else
+    {
+      dev = dpbp->dpb_device;
+      attr = dev->dh_attr;
     }
   } /* switch */
 
@@ -186,6 +183,8 @@
   {
     CharReqHdr.r_cat = r->CH;            /* category (major) code */
     CharReqHdr.r_fun = r->CL;            /* function (minor) code */
+    CharReqHdr.r_si = r->SI;             /* contents of SI and DI */
+    CharReqHdr.r_di = r->DI;
     CharReqHdr.r_io = MK_FP(r->DS, r->DX);    /* parameter block */
   }
   else
@@ -194,6 +193,7 @@
     CharReqHdr.r_trans = MK_FP(r->DS, r->DX);
   }
   CharReqHdr.r_length = sizeof(request);
+  CharReqHdr.r_unit = dpbp->dpb_subunit;
   CharReqHdr.r_status = 0;
 
   switch (r->AL)
@@ -256,7 +256,7 @@
 
     case 0x09:
         {
-          const struct cds FAR *cdsp = get_cds(CharReqHdr.r_unit);
+          const struct cds FAR *cdsp = get_cds(unit);
           if (cdsp == NULL)
             return DE_INVLDDRV;
           if (cdsp->cdsFlags & CDSSUBST)
diff -Naur cvs/kernel/kernel/nls.c src/kernel/kernel/nls.c
--- cvs/kernel/kernel/nls.c     2004-07-09 04:16:28.000000000 +0200
+++ src/kernel/kernel/nls.c     2004-08-13 11:57:52.000000000 +0200
@@ -109,7 +109,7 @@
 /*
  *     Call NLSFUNC to load the NLS package
  */
-COUNT muxLoadPkg(UWORD cp, UWORD cntry)
+COUNT muxLoadPkg(int subfct, UWORD cp, UWORD cntry)
 {
   UWORD id; /* on stack, call_nls in int2f.asm takes care of this
              * if DS != SS */
@@ -131,7 +131,7 @@
   /* OK, the correct NLSFUNC is available --> load pkg */
   /* If cp == -1 on entry, NLSFUNC updates cp to the codepage loaded
      into memory. The system must then change to this one later */
-  return muxGo(NLSFUNC_LOAD_PKG, 0, cp, cntry, 0, 0, 0);
+  return muxGo(subfct, 0, cp, cntry, 0, 0, 0);
 }
 
 STATIC int muxBufGo(int subfct, int bp, UWORD cp, UWORD cntry,
@@ -367,15 +367,30 @@
 }
 STATIC COUNT DosSetPackage(UWORD cp, UWORD cntry)
 {
+  /* Right now, we do not have codepage change support in kernel, so push
+     it through the mux in any case. */
+
+  return muxLoadPkg(NLSFUNC_LOAD_PKG2, cp, cntry);
+}
+
+STATIC COUNT nlsLoadPackage(struct nlsPackage FAR * nls)
+{
+
+  nlsInfo.actPkg = nls;
+
+  return SUCCESS;
+}
+STATIC COUNT DosLoadPackage(UWORD cp, UWORD cntry)
+{
   struct nlsPackage FAR *nls;   /* NLS package to use to return the info from */
 
   /* nls := NLS package of cntry/codepage */
   if ((nls = searchPackage(cp, cntry)) != NULL)
     /* OK the NLS pkg is loaded --> activate it */
-    return nlsSetPackage(nls);
+    return nlsLoadPackage(nls);
 
   /* not loaded --> invoke NLSFUNC to load it */
-  return muxLoadPkg(cp, cntry);
+  return muxLoadPkg(NLSFUNC_LOAD_PKG, cp, cntry);
 }
 
 STATIC void nlsUpMem(struct nlsPackage FAR * nls, VOID FAR * str, int len)
@@ -558,7 +573,7 @@
 #ifndef DosSetCountry
 COUNT DosSetCountry(UWORD cntry)
 {
-  return DosSetPackage(NLS_DEFAULT, cntry);
+  return DosLoadPackage(NLS_DEFAULT, cntry);
 }
 #endif
 
@@ -630,6 +645,7 @@
       /* Does not pass buffer length */
       return nlsGetData(nls, CL, MK_FP(ES, DI), 512);
     case NLSFUNC_LOAD_PKG:
+      return nlsLoadPackage(nls);
     case NLSFUNC_LOAD_PKG2:
       return nlsSetPackage(nls);
     case NLSFUNC_YESNO:

Reply via email to