Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DDT / UDSC / UPB structure differs from MS-DOS v6.22/v7.00/v7.10 (and EDR-DOS) #143

Open
ecm-pushbx opened this issue Feb 24, 2024 · 1 comment

Comments

@ecm-pushbx
Copy link
Contributor

The structure is defined here:

/* DOS 4.0-7.0 drive data table (see RBIL at INT2F,AX=0803) */

The MS-DOS v6 and v7.00 structure is incompletely described in https://fd.lod.bz/rbil/interrup/dos_kernel/2f0803.html#table-02603

I would suggest dropping ddt_offset, setting the hidden sectors to the int 13h unit absolute LBA of the file system start, and if ddt_descflag & DF_FIXED is set then setting ddt_part = 1, ddt_abscyl = 0. Further, the 6 reserved bytes in ddt_reserved should be dropped for with-FAT32 kernels but both of the EBPBs should be expanded with 12 reserved bytes. This would make the DDT structure completely compatible with MS-DOS v6.22/v7.00 (for without-FAT32) or v7.10 (for with-FAT32), for reading. That is, except for if someone modifies a DDT structure or creates a new DDT structure and clears flag 400h (disabling LBA) and/or sets different ddt_part and ddt_abscyl.

Refer to details in the SvarDOS EDR-DOS repo: SvarDOS/edrdos#48 (comment)

Quoting:

MS-DOS v6.22 certainly doesn't have a field at the position of FreeDOS's ddt_offset. Its UPBs are 64h bytes in size. After running int 2Fh function 0803h the pointer arithmetic shows this:

-h word [ds:di] - di
0064  decimal: 100
-

The UPB listing in the Interrupt List says:

---fixed media---
 47h	WORD	partition (FFFFh = primary, 0001h = extended)
		always 0001h for DOS 5+
 49h	WORD	absolute cylinder number of partition's start on physical drive
		(FFFFh if primary partition in DOS 4.x)

These fields are used in this way if the "fixed media" flag in the word at 23h is set. MS-DOS v6.22's block device does still support a value other than 1 in the word 47h, but a primary partition does actually have the value 1 there and then a value of 0 in the word 49h.

The word 49h is added to the Cylinder value of the CHS tuple -- after the tuple is calculated from the "in-extended partition" logical block address (sector number in partition plus hidden sectors). The word 49h holds the Cylinder value of the start of the extended partition that holds the logical partition. In a test case created using MS-DOS v6.22 fdisk, all hidden sectors of 3 partitions (one primary, two logical) are 63 but the word 49h is different for all three.

Now to test MS-DOS v7.10 ...

I actually checked MS-DOS v7.00 first, which does not support FAT32 but does support LBA. If the primary partition type is 0Eh (FAT12/FAT16 LBA) or a partition is within an extended partition type 0Fh (Extended LBA) then LBA is used to access it. This is marked by bit 10 (flag 400h) in the flags word at 23h. (Which is also used by FreeDOS to mark to use LBA.)

If the LBA flag is set for MS-DOS v7.00, then the hidden sectors at dword 17h contain the start of the partition within the entire unit, not just within the extended partition. The instsect /G auto switch will also detect this hidden sectors value then. There is a check for the word at 47h being 1 and the word at 49h being 0. If word 47h != 1 then skip next part. If word 47h == 1 and word 49h == 0 then skip next part too. (The observed LBA logical partition had word 47h = 1 and word 49h = 0.) Otherwise add dword 17h again. I'm not sure if this code path is ever taken, it seems like it would add the hidden sectors twice.

MS-DOS v7.10 functions largely like v7.00, the 400h flag is for LBA access and also correlates to the hidden sectors containing the int 13h unit total LBA sector number. The partition types apparently determine whether flag 400h is set. If it is clear then word 79h == 1 means to add word 7Bh to the Cylinder part of the CHS tuple. (Different offsets than in v6.22 and v7.00 due to the EBPBs.) Obviously if you fill the hidden sectors with the unit total LBA and word 7Bh = 0 then even in CHS mode the kernel will find the correct data position, and would work with extended partitions not on cylinder boundaries as well.

What's different is that each BPB in the UPB is a FAT32 EBPB, with the FAT32-specific parts zeroed out except for FSINFO sector and backup sector both filled with 0FFFFh. The EBPB does contain the 12 reserved bytes at its trail, unlike FreeDOS-with-FAT32. Also unlike FreeDOS-with-FAT32 the field of 6 reserved bytes behind one of the BPBs is dropped instead.

EDR-DOS also changes the UDSC (unit descriptor) layout yet again. https://hg.pushbx.org/ecm/edrdos/file/6497e3a1a0c7/drbio/udsc.equ#l35 contains an EBPB length of 41 (29h), like FreeDOS-with-FAT32 excluding the 12 reserved bytes. The trailing 6 bytes (7 bytes here due to a byte presumably not used by EDR-DOS) is also preserved, alike FreeDOS-with-FAT32 and unlike MS-DOS v7.10. EDR-DOS adds two new fields after the common structure, totalling 4 bytes. (I think that brings EDR-DOS to the same UDSC length as FreeDOS-with-FAT32, because FD's ddt_offset also takes up 4 bytes. Yes, both are 88h bytes. As opposed to 64h for MS-DOS v6.22/v7.00, 96h for MS-DOS v7.10, and 68h for FreeDOS-without-FAT32.)

I will have to study to see whether EDR-DOS and FreeDOS can use a compatible content in the partition fields to match the MS-DOS v7.xx content, ie a 1 and a 0 respectively. In that case the hidden sector could always be the total unit LBA like for MS-DOS v7 when LBA is enabled.

@ecm-pushbx
Copy link
Contributor Author

Note for kernel using software: The UPB size can usually be detected from the offset of the drive B: (second) UPB minus the offset of the drive A: (first) UPB, if they are both in the same segment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant