Hi Christian,

> the Int 0x21, AX=0x7305, CX=0xFFFF handler (FAT32 - EXTENDED ABSOLUTE
> DISK READ/WRITE) found in "inthndlr.c", 355 ff., is implemented in a
> very strict way ... it corresponds to www.ctyme.com/intr/rb-3229.htm

This is RBIL, Ralph Brown's Interrupt List - usually pretty useful.

> but some DOS applications I recently used do not set SI to 0x00 on read
> operations, instead they set this value (incorrectly?) to 0x6000 (as
> write operations are set correctly to 0x6001 - see bits 14-13)...

This is interesting. The RBIL item D-217305CXFFFF explains that
the low bit of SI is 0 read / 1 write while bit 13/14 indicate
the accessed area: 0x0001 write any, 0x2001 write FAT, 0x4001
write directory, 0x6001 write file. It also says that reads do
not specify such a "type flag", but I agree with you that there
is no need to reject "typed reads".



> following code in "inthndlr.c":
>       if (r->CX != 0xffff || ((r->SI & 1) == 0 && r->SI != 0)
>           || (r->SI & ~0x6001)) ... DE_INVLDPARM ...

This implementation is in int int21_fat32(lregs *r) case 0x05...
the test says that no bits beyond 0, 13, 14 may be set, but it
also says that if bit 0 is 0 then no type may be set and this
is what breaks your compatibility. However, if you relax the
test, you also have to change this:

      if (r->SI == 0) <-- do not leave this test as "... == 0"
...

Otherwise all "typed reads" would turn into writes!



I suggest the following patch. If there are no objections, it
can go into stable kernel 2038 :-). Christian, please do test
this patch to see if it fixes your problem. In inthndlr.c:

-      if (r->CX != 0xffff || ((r->SI & 1) == 0 && r->SI != 0)
-          || (r->SI & ~0x6001))
+      if (r->CX != 0xffff || (r->SI & ~0x6001))

-      if (r->SI == 0)
+      if ((r->SI & 1) == 0) /* while uncommon, reads CAN have type hints */



The rest of this mail is more philosophical... Read it only
if you are interested in better kernel performance ;-).



QUESTION to the kernel experts: It seems that only getblk but
not dskxfer does anything with BUFFERS and, while doing so,
would be able to actually use the "type of sector contents"
hint for anything? Plus you would HAVE to use type hints when
you write things (because "if it is fat, update both copies")?

See uses of BFR_DATA BFR_DIR BFR_FAT type hints for BUFFERS,
in blockio.c, fat*.c and inthndlr.c although the latter only
clears the type hint for a buffer with the boot sector.

Note that rwblock (file and directory cluster access) can call
dskxfer directly, too. Calling getblk happens via getblock or
getblockOver, mostly from fat*.c for files and directories;
fat*.c contains rwblock which calls dskxfer for multi sector
access and getblock* for single sectors.

Would it make sense if int21_fat32 could call either dskxfer
or getblock* depending on whether you are doing multi sector
access? Would it make sense to give getblock* and/or rwblock
an optional parameter for the "type hint flag", for example
for more efficient or safer use of BUFFERS?

Eric

PS: What happens if you access the same sector via getblock
and via dskxfer but the BUFFER used by getblock is dirty?
Will dskxfer realize that there is conflicting write data?


-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace
_______________________________________________
Freedos-kernel mailing list
Freedos-kernel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/freedos-kernel

Reply via email to