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:
