Re: DOSdosfsck 2.8.0 beta release! -> "int" 25/26 disk preferred!
Eric Auer <[email protected]>
| Newsgroups | gmane.os.freedos.devel |
|---|---|
| Message-ID | <[email protected]> |
Hi Tom et al,
I agree that the BIOS access is a kludge (and the way e2fstools use it
in their DOS version is very sketchy, I do not think e2fsck for DOS
does work properly most of the time).
But I could not find any evidence that DJGPP has direct int 25/26 support.
Whatever, I would prefer if the port would use int 25/26 anyway.
For this, you must use:
http://www.delorie.com/djgpp/doc/libc-2.02/
> int86x:
http://www.delorie.com/djgpp/doc/libc-2.02/libc_433.html
in combination with a special strategy to use a buffer that is
beyond the 1 MB boundary:
http://www.delorie.com/djgpp/v2faq/faq18_2.html
#include <sys/types.h>
#include <sys/movedata.h>
#include <dpmi.h>
#include <go32.h>
char * local_currency (void)
{
__dpmi_regs regs;
regs.x.ax = 0x3800; /* AH = 38h, AL = 00h */
regs.x.ds = __tb >> 4; /* transfer buffer address in DS:DX */
regs.x.dx = __tb & 0x0f;
__dpmi_int (0x21, ®s); /* call DOS */
if (regs.x.flags & 1) /* is carry flag set? */
/* The call failed; use the default symbol. */
return strdup ("$");
else
{
/* The call succeeded. The local currency symbol is stored
as an ASCIIZ string at offset 2 in the transfer buffer. */
char *p = (char *)malloc (2);
if (p != 0)
dosmemget (__tb + 2, 2, p);
return p;
}
}
The __tb is a special buffer of 2..16k size that is normally already
allocated. If you need a better buffer, you need to do more of the
stuff described in the page linked above (faq18_2.html). However, it
is probably better to compile with the default buffer size of 16k and
split disk access into 16k chunks.
Here is how int 25 and int 26 have to be used:
(Do not forget to use intdos, int 21, ah=0d, to flush/write back buffers
when dosfsck is done!?)
1) For SMALL partitions and floppies:
--------D-25---------------------------------
INT 25 - DOS 1+ - ABSOLUTE DISK READ (except partitions > 32M)
AL = drive number (00h = A:, 01h = B:, etc)
CX = number of sectors to read (not FFFFh)
DX = starting logical sector number (0000h - highest sector on drive)
DS:BX -> buffer for data
Return: CF clear if successful
CF set on error
AH = status (see #02547)
AL = error code (same as passed to INT 24 in DI)
AX = 0207h if more than 64K sectors on drive -- use new-style call
may destroy all other registers except segment registers
--------D-26---------------------------------
INT 26 - DOS 1+ - ABSOLUTE DISK WRITE (except partitions > 32M)
AL = drive number (00h = A:, 01h = B:, etc)
CX = number of sectors to write (not FFFFh)
DX = starting logical sector number (0000h - highest sector on drive)
DS:BX -> data to write
Return: CF clear if successful
CF set on error
AH = status (see #02547)
AL = error code (same as passed to INT 24 in DI)
AX = 0207h if more than 64K sectors on drive -- use new-style call
may destroy all other registers except segment registers
2) For bigger partitions:
--------D-25----CXFFFF-----------------------
INT 25 - DOS 3.31+ - ABSOLUTE DISK READ (32M-2047M hard-disk partition)
CX = FFFFh
AL = drive number (0=A, 1=B, etc)
DS:BX -> disk read packet (see #02548)
Return: CF clear if successful
CF set on error
AH = status (see #02547)
AL = error code (same as passed to INT 24 in DI)
AX = 0207h for FAT32 drive -- use INT 21/AX=7305h
may destroy all other registers except segment registers; Win9X always
sets SI to 0000h due to an apparent coding bug
Format of disk read packet:
Offset Size Description (Table 02548)
00h DWORD sector number
04h WORD number of sectors to read
06h DWORD transfer address
--------D-26----CXFFFF-----------------------
INT 26 - DOS 3.31+ - ABSOLUTE DISK WRITE (32M-2047M hard-disk partition)
CX = FFFFh
AL = drive number (0=A, 1=B, etc)
DS:BX -> disk write packet (see #02552)
Return: CF clear if successful
CF set on error
AH = status (see #02547)
AL = error code (same as passed to INT 24 in DI)
may destroy all other registers except segment registers
Format of disk write packet:
Offset Size Description (Table 02552)
00h DWORD sector number
04h WORD number of sectors to read
06h DWORD transfer address
3) WARNING - Pitfalls!
Although this is called an INT in intlist, the Notes: clarify that
it is a FAR CALL. So you must use far call functionality to use it,
after reading the interrupt vector (for example with intdosx!?) to
get the entry point.
The "transfer address" values and the ds:bx pointers must be in DOS
far pointer style, which needs special translation to access the same
area of RAM from protected mode (from dosfsck, that is).
You must allocate both the transfer buffer and, in "big partition"
case, the "disk write packet" buffer. I recommend that you put the
latter in the __tb described above, and maybe even the former (in
what is left of __tb). In that case you must of course use the above-
mentioned methods to get both the DOS style and the protected mode
style pointers to __tb.
For doing a call far into the DOS task from protected mode, you use:
http://www.delorie.com/djgpp/doc/libc-2.02/libc_399.html
_go32_dpmi_simulate_fcall If you do not want to use go32 specific stuff, you can use:
http://www.delorie.com/djgpp/doc/libc-2.02/libc_249.html
__dpmi_simulate_real_mode_procedure_retf
or, alternatively:
http://www.delorie.com/djgpp/doc/libc-2.02/libc_250.html
__dpmi_simulate_real_mode_procedure_retf_stack
(where you can put stuff on the stack as well, not really
needed for "int" 25/26 far calling...)
I hope some wizard of djgpp can add the needed something to the
io.c (as said, please leave the ability to open image files intact!
Just do something like "if filename is a drivename, open as drive.
Otherwise open as file" and act depending upon a drive/file flag
later in seek/read/write functions. I would prefer int 25/26 over biosdisk.
By the way, even if YOU make dosfsck fully usable with DOS, please take
the time to mention ME in the code or readme. I forgot to pat my own
shoulders in the current dosdosfsck-2.8.0.zip ;-).
Eric
PS: The "int" 25/26 descriptions are cut and paste out of Ralf Browns
Interrupt List, Release 61. It really sucks, but of course WINDOWS 98
uses yet ANOTHER interface for FAT32 drives: int 21, ax=7305 - and of
course you need to allocate/have a buffer again, as intdosx does not
autodetect the fact that a buffer is involved as far as I know, in this
case.
--------D-217305CXFFFF-----------------------
INT 21 - Windows95 - FAT32 - EXTENDED ABSOLUTE DISK READ/WRITE
AX = 7305h
CX = FFFFh
DL = drive number (01h=A:, etc.)
SI = read/write mode flags (see #01791)
DS:BX -> disk I/O packet (see #02548 at INT 25)
Return: CF clear if successful
CF set on error
AX = error code
Note: one can not specify the default drive (DL=00h) for this function.
Bitfields for Extended Absolute Disk Read/Write mode flags:
Bit(s) Description (Table 01791)
0 direction (0=read, 1=write)
12-1 reserved (0)
14-13 write type (should be 00 on reads)
00 unknown data
01 FAT data
10 directory data
11 file data
15 reserved (0)
[This mail is a reply to Toms warning not to use BIOS disk access but better
"int" 25/26, to make sure consistend drive letters are used all the time...]