FDOS / fdisk

Fixed Disk Setup Program - manages partitions using the MBR partitioning scheme
GNU General Public License v2.0
44 stars 14 forks source link

Implement different DLA methods #86

Open boeckmann opened 1 month ago

boeckmann commented 1 month ago

Currently there is an incompatibility between the drive letter assignment of the (E)DR-DOS kernel and FDISK, as FDISK follows the FreeDOS (and Microsoft) way of assigning drive letters to partitions. But DR-DOS handles this differently.

We should detect if running under DR-DOS and adapt to its drive letter assignment.

A new FDISK config variable DLA will be introduced, defaulting to zero. This means that FDISK will try to auto-adapt its DLA to the operating system. DLA=1 means explicit FreeDOS DLA algorithm, while DLA=2 means explicit DR-DOS DLA algorithm.

Notice: The DLA of the FreeDOS kernel may be changed via a kernel config variable. There is currently no easy way to detect which DLA the FreeDOS kernel uses. But the default is to match the Microsoft way of doing it, and this is what FDISK assumes.

boeckmann commented 1 month ago

implemented by 1c9271f

PerditionC commented 1 month ago

For increased compatibility you could use the method described in DOS Internals book. I.e. the drivparam/driver.sys interface, INT 2F/08xx - GET DRIVE DATA TABLE LIST *1

based on snippet from DOS Internals DRVINFO tool:

/* takes DOS drive where 2=C:,3=D:,... and returns # to use for BIOS int 13h call (FFh if no match) */
static BYTE GetBIOSDriveNumber(BYTE dosdrive)
{
    struct ddtstruct FAR *pddt; /* see hdr\device.h in FreeDOS kernel source */

    pddt = GetDOSDriveTable();

    /*  Follow the chain (each table contains a far pointer to another - not
    necessarily in ascending drive order) to the table for the specified
    DOS drive number.  Another field in the table gives the BIOS drive
    number that is used for int 13h access.  */

    for(; (WORD)pddt != 0xFFFF; pddt = pddt->ddt_next) {
    if (pddt->ddt_logdriveno == dosdrive) 
            return pddt->ddt_driveno;
    }

    /* if made it here, then either invalid DOS drive or not in DOS's 
       drive table, i.e. not handled by DOS BIOS block disk driver. 
       Return unknown - at this point the only way to map would be
       to hook int 13h and make a call to DOS to force it to access
       drive and see which call matches.  We just return failure sentinel.
    */

    return 0xFF;
}

/* validate call should be available, query for internal DOS structure with DOS drive mappings */
struct ddtstruct FAR * GetDOSDriveTable(void)
{
    if (_osmajor < 4) {
    nomatch:
    return ((struct ddtstruct FAR *) -1);
    }

    /* DS:DI -> first drive data table in list
       Supported by Novell DOS 7+ (using the MS-DOS 4+ data table format)
    */
    _asm {
        mov     ax,0800h
        int     2Fh
        cmp     al,0FFh
        jnz     nomatch

        push    ds
        mov     ax,0803h
        int     2Fh
        mov     ax,di
        mov     dx,ds
        pop     ds
    }
}

[*1] the FreeDOS kernel doesn't currently implement this, so I'd need to actually finish my work on it and publish it.

PerditionC commented 1 month ago

For fdisk, you may need the reverse function, pass in BIOS# and return DOS drive# (ie swap compare and return ddt_driveno/ddt_logdriveno).

boeckmann commented 1 month ago

@PerditionC I could use this to make sure the user deletes the correct drive. But I cannot use this to detect die DLA method if the user starts with an empty partition table.

Is there any benefit of using INT2F instead simply peeking at the LoL for getting a pointer to the first ddt?

boeckmann commented 1 month ago

There is also the problem that drive letters change with the first modification and are "out of sync" with the letters known to the OS.

ecm-pushbx commented 1 month ago

Is there any benefit of using INT2F instead simply peeking at the LoL for getting a pointer to the first ddt?

  1. It's more portable, 2. I don't think the List of Lists, being a DOS structure, has any pointers to the chain of DDTs / UDSCs / UBPBs, being a BIO structure.
PerditionC commented 1 month ago

at least FreeDOS kernel doesn't, it's pointed to by dyn variable

boeckmann commented 1 month ago

You are right, I confused the DDT / UDSC structure with the DPB / DDSC structure. I need the DDT to get the partition offset.

PerditionC commented 1 month ago

makes sense, I was thinking of a good interface the kernel could expose current drive letter assignment and realized it already existed, so wanted to mention it.

boeckmann commented 1 month ago

Some time ago I think Jerome asked me if partition activation based on drive letter could be implemented. This INT2Fh,08 would be quite useful for it.

Also it would be very useful if kernel config like DLA method could be queried by applications.

boeckmann commented 1 month ago

relates to https://github.com/FDOS/fdisk/issues/81