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: