Closed stsp closed 7 years ago
assuming "HDD" is a hard disk:
MS-DOS/PC DOS since version 5.0, and later operating systems, assigns drive letters according to the following algorithm:
Assign the drive letter A: to the first floppy disk drive (drive 0), and B: to the second floppy disk drive (drive 1). If only one physical floppy is present, drive B: will be assigned to a phantom floppy drive mapped to the same physical drive and dynamically assigned to either A: or B: for easier floppy file operations. If no physical floppy drive is present, DOS 4.0 will assign both A: and B: to the non-existent drive, whereas DOS 5.0 and higher will invalidate these drive letters. If more than two physical floppy drives are present, DOS versions prior to 5.0 will assign subsequent drive letters, whereas DOS 5.0 and higher will remap these drives to higher drive letters at a later stage; see below. Assign a drive letter to the first active primary partition recognized upon the first physical hard disk. DOS 5.0 and higher will ensure that this will become drive letter C:, so that the boot drive will either have drive letter A: or C:. Assign subsequent drive letters to the first primary partition upon each successive physical hard disk drive (DOS versions prior to 5.0 will probe for only two physical harddisks, whereas DOS 5.0 and higher support eight physical harddisks). Assign subsequent drive letters to every recognized logical partition present in the first extended partition, beginning with the first hard drive and proceeding through successive physical hard disk drives. DOS 5.0 and higher: Assign drive letters to all remaining primary partitions, beginning with the first hard drive and proceeding through successive physical hard disk drives. DOS 5.0 and higher: Assign drive letters to all physical floppy drives beyond the second physical floppy drive. Assign subsequent drive letters to any block device drivers loaded in CONFIG.SYS via DEVICE statements, e.g. RAM disks. Assign subsequent drive letters to any dynamically loaded drives via CONFIG.SYS INSTALL statements, in AUTOEXEC.BAT or later, i.e. additional optical disc drives (MSCDEX etc.), PCMCIA / PC Card drives, USB or Firewire drives, or network drives. Only partitions of recognized partition types are assigned letters. In particular, "hidden partitions" (those with their type ID changed to an unrecognized value, usually by adding 10h) are not. MS-DOS/PC DOS versions 4.0 and earlier assign letters to all of the floppy drives before considering hard drives, so a system with four floppy drives would call the first hard drive E:. Starting with DOS 5.0, the system ensures that drive C: is always a hard disk, even if the system has more than two physical floppy drives.
So a: and b: are always floppy disk drives. (real/phantom)
So a: and b: are always floppy disk drives. (real/phantom)
No because of this:
whereas DOS 5.0 and higher will invalidate these drive letters.
Unfortunately this invalidation doesn't seem to work without
my patch. But I admit that my patch was made w/o knowing
enough of the context.
Do you happen to know where is the code that is supposed
to invalidate the first 2 drive letters?
If no physical floppy drive is present, DOS 4.0 will assign both A: and B: to the non-existent drive, whereas DOS 5.0 and higher will invalidate these drive letters.
In fact, my patch makes it to the 4.0 way - assign both to non-existing. If only I knew what is the difference: assign to non-existing or to invalidate? Can I suppose there is no difference for the user, just some coding detail differes?
well that's a good question Let's see if I can find out via the interrupt list of Ralf Brown. Or maybe someone else got an idea here.
The question is -- if we invalidate a drive. is that only towards the user interface or are they still reserved but differently error'd out?
I've also found out that setting maxdrv
to
1 has the same effect of fixing this problem.
But the drives are not invalidated in both cases:
I can still go to A:
and only if I do some dir
there, then I see an error. Perhaps the better
fix would be the one that will return an error
when you just typed A:
.
so:
1) a drive select does not error, 2) accessing it (if the disk is not there or the drive) gives an error.
Let's see how that affects compatibility regarding DOS v5 itself.
so:
With both changes I tried - yes. W/o changes - I don't know as then it doesn't boot.
I'll try to debug a bit more.
OK, I uploaded the new patch. Now it fully complies to the quoted docs: A and B are now invalid when no FDD installed.
I've found the disparity:
diff --git a/SOURCES/src/kernel/MOSINIT2.ASM b/SOURCES/src/kernel/MOSINIT2.ASM
index 04e6732..4400ed1 100644
--- a/SOURCES/src/kernel/MOSINIT2.ASM
+++ b/SOURCES/src/kernel/MOSINIT2.ASM
@@ -3448,7 +3448,6 @@ notvna:
; partition #)
and al,7fh ; set mos drive id
- add al,2 ; start hard drives at c
push es
push ax
int 12h ; get memory size
So if this addition of 2 is removed, then MOS boots fine from A:. So either that, or reserve 2 when no floppies are found, as in my patch - then it boots from C and A,B are invalidated.
So I think now all bits and pieces are connected. Let me know what kind of fix do you prefer.
What does DOS 5 do when there are no floppies, is its boot drive C: or A: ?
C of course. Rhetorical question? :)
diff --git a/SOURCES/src/kernel/MOSDDINT.ASM b/SOURCES/src/kernel/MOSDDINT.ASM
index 9e29790..14efb6e 100644
--- a/SOURCES/src/kernel/MOSDDINT.ASM
+++ b/SOURCES/src/kernel/MOSDDINT.ASM
@@ -581,6 +581,15 @@ ddinit0 proc near
pop es
pop bx
mov es:[bx+10],dl ; number of drives actually installed
+ cmp [scbdevs],0 ; see if assigning floppies
+ jne ddi02
+ cmp dl,scbhddmin
+ jae ddi01
+ mov dl,scbhddmin
+ddi01:
+ mov [scbflops],dl
+ddi02:
+ inc [scbdevs]
add [scbdrivs],dl ; increasing total number of drives in system
jmp ddi0b
ddi0a:
diff --git a/SOURCES/src/kernel/MOSINIT2.ASM b/SOURCES/src/kernel/MOSINIT2.ASM
index 04e6732..ae63ad6 100644
--- a/SOURCES/src/kernel/MOSINIT2.ASM
+++ b/SOURCES/src/kernel/MOSINIT2.ASM
@@ -3448,7 +3448,7 @@ notvna:
; partition #)
and al,7fh ; set mos drive id
- add al,2 ; start hard drives at c
+ add al,[scbflops] ; start hard drives at c
push es
push ax
int 12h ; get memory size
diff --git a/SOURCES/src/kernel/MOSSCBDF.INC b/SOURCES/src/kernel/MOSSCBDF.INC
index 371dbcd..2661d57 100644
--- a/SOURCES/src/kernel/MOSSCBDF.INC
+++ b/SOURCES/src/kernel/MOSSCBDF.INC
@@ -114,7 +114,7 @@ public scblastw1, scblastw2, scbrdriv, scbirqd0a, scbirqd0b, scbirqd0c
public scbirqd0d, scbirqd0e, scbirqd0f, scbinit, scbirqbnk, SCBSAVE, scbcon417
public scbkbrate, scbout60, scbin60, scbmconly, scbi15off, scbnorst
public scbpost, SCB_COM_owner, SCB_COM_timeout, scbdrtcb, scbnoi5
-public scbvdrflg, scbdopflg, scbdosver
+public scbvdrflg, scbdopflg, scbdosver, scbflops, scbdevs, scbhddmin
scbtcbpf dw 0 ;* pointer to first task control block
scbtcbpl dw 0 ;* pointer to last tcb
@@ -211,6 +211,9 @@ scbcursz dw 0ffffh ; used in mosheman
scbcurad dw 0 ; used in mosheman
scbavsiz dw 0 ; used in mosheman
scbdrivs db 0 ; # active drive units
+scbflops db 0 ; # active floppy units
+scbhddmin equ 2 ; start hdd from c or above
+scbdevs db 0 ; # active block devices
scbnoswt db 0,0 ; mos no switch flag (like dos critical flag)
; to be set if no task switch is to occur
; a 0 byte follows since some apps check the word
diff --git a/SOURCES/src/kernel/MOSSCBEX.INC b/SOURCES/src/kernel/MOSSCBEX.INC
index ef9a912..b67a815 100644
--- a/SOURCES/src/kernel/MOSSCBEX.INC
+++ b/SOURCES/src/kernel/MOSSCBEX.INC
@@ -57,6 +57,9 @@ extrn scbcursz:word ; mosheman usage
extrn scbcurad:word ; mosheman usage
extrn scbavsiz:word ; mosheman usage
extrn scbdrivs:byte ; # active drive units
+extrn scbflops:byte ; # active floppy units
+extrn scbdevs:byte ; # active block devices
+extrn scbhddmin:abs ; start hdd from this number or more
extrn scbnoswt:byte ; mos no switch flag
extrn scbtskfg:byte ; task selection flags
extrn scbdrvr:dword ; -> first device driver in list
Something like this should work as a full-featured fix. But unfortunately updated externs require the full rebuild, whereas I can only rebuild the kernel. :(
I'll keep the PR open and see if I can set up a full build system.
Currently some health things slow down the stuff a bit.
@dcoshea maybe you can rebuild with the patch and put the binaries somewhere? If the patch works as expected, I will convert it into the PR. So far this PR has a minimal patch that was tested and works fine.
How about this change? SOURCES/src/kernel/MOSINIT2.ASM @@ -4091,7 +4091,7 @@ no286a:
mov [tcbcdbpf],0 ; clear pointer to cdb
mov [tcbcdbpc],0 ; clear pointer to cdb
mov [tcbndriv],0 ; clear # of drives
- mov [scbdrivs],0 ; clear any count of drives for re-init
+ mov [scbdrivs],2 ; clear any count of drives for re-init (always make room for A: and B: floppies)
mov [scbbdbpf],0 ; clear pointer to 1st block device
How do you expect this to work when there are floppies? We only need to compensate when there are none, or, alternatively, tell the boot code to evaluate to A properly. My last patch does this, but not tested as of yet. I will work on getting it tested.
Sure my naive change will not work. BTW I think I found another bug SOURCES/src/kernel/MOSDDINT.ASM @@ -871,7 +871,7 @@ mosbd1b:
mosbd2:
pop es ; address of bdb
push ax ; save error code
- mov al,1
+ mov ah,1 ; the intention is to remove memory block
mov al,'B'
Yes, good catch! But this bug isn't observable for me, as I believe it only produces the memory leak. You should try to submit this fix as a separate PR.
merged. As stsp states -- please have a separate PR for the memleak.
OK, in this case I'll open a new PR once I have the bigger patch finally tested.
This is a quick-fix that prevents HDD from moving to A:. It is not clear why HDD does not work on A:, maybe it should? Maybe someone else can code up the more intrusive fix.