Skip to content

Conversation

@ecm-pushbx
Copy link
Contributor

Running prior to this commit, a /K switch with a name at a certain position will write all-blanks into the boot sector loader. If that happens, lDOS instsect will not detect a valid load file name:

C:\>sys a: /bootonly /k ldos.com
System transferred.

C:\>instsect /bo a:
Detected FAT12 FS.
Keeping original sector loader.
Sector valid, FS ID match and proper jump.
Type heuristic: "FreeDOS (FreeDOS)"
No name detected.
Unit selection code not found in sector. Keeping as is.
Part info code not found in sector. Keeping as is.
Query geometry code not found in sector. Keeping as is.
Auto LBA detection (HDD only) found in sector. Keeping as is.
Previous geometry: 2 CHS Heads, 18 CHS Sectors, 0 Hidden
Writing boot sector to sector.
C:\>

Running after this commit sets the name as desired:

C:\>sys a: /bootonly /k ldos.com
System transferred.

C:\>instsect /bo a:
Detected FAT12 FS.
Keeping original sector loader.
Sector valid, FS ID match and proper jump.
Type heuristic: "FreeDOS (FreeDOS)"
1st name: "LDOS.COM"
Unit selection code not found in sector. Keeping as is.
Part info code not found in sector. Keeping as is.
Query geometry code not found in sector. Keeping as is.
Auto LBA detection (HDD only) found in sector. Keeping as is.
Previous geometry: 2 CHS Heads, 18 CHS Sectors, 0 Hidden
Writing boot sector to sector.
C:\>

For reference, the libi86 implementation of _dos_findfirst also sets the DTA to the user buffer rather than copying around the resulting search record. So it is likely that Turbo C or Watcom do it similarly to this:

https://gitlab.com/tkchia/libi86/-/blob/3ecc4164999a5807c40cf2c159dc94dd07f7df03/host-gcc/dos/dos-findfirst.c#L43

(I may add a commit addressing #156 to this PR later.)

Running prior to this commit, a /K switch with a name at a certain
position will write all-blanks into the boot sector loader. If that
happens, lDOS instsect will not detect a valid load file name:

C:\>sys a: /bootonly /k ldos.com
System transferred.

C:\>instsect /bo a:
Detected FAT12 FS.
Keeping original sector loader.
Sector valid, FS ID match and proper jump.
Type heuristic: "FreeDOS (FreeDOS)"
No name detected.
Unit selection code not found in sector. Keeping as is.
Part info code not found in sector. Keeping as is.
Query geometry code not found in sector. Keeping as is.
Auto LBA detection (HDD only) found in sector. Keeping as is.
Previous geometry: 2 CHS Heads, 18 CHS Sectors, 0 Hidden
Writing boot sector to sector.
C:\>

Running after this commit sets the name as desired:

C:\>sys a: /bootonly /k ldos.com
System transferred.

C:\>instsect /bo a:
Detected FAT12 FS.
Keeping original sector loader.
Sector valid, FS ID match and proper jump.
Type heuristic: "FreeDOS (FreeDOS)"
1st name: "LDOS.COM"
Unit selection code not found in sector. Keeping as is.
Part info code not found in sector. Keeping as is.
Query geometry code not found in sector. Keeping as is.
Auto LBA detection (HDD only) found in sector. Keeping as is.
Previous geometry: 2 CHS Heads, 18 CHS Sectors, 0 Hidden
Writing boot sector to sector.
C:\>

For reference, the libi86 implementation of _dos_findfirst also
sets the DTA to the user buffer rather than copying around the
resulting search record. So it is likely that Turbo C or Watcom
do it similarly to this:

https://gitlab.com/tkchia/libi86/-/blob/3ecc4164999a5807c40cf2c159dc94dd07f7df03/host-gcc/dos/dos-findfirst.c#L43
@ecm-pushbx
Copy link
Contributor Author

To clarify, the application's command line at PSP:80h is corrupted by the find first call. But the "ldos.com" string still lives there until the point it is read later at

kernel/sys/sys.c

Lines 1758 to 1779 in 9b9b5b1

{
int i = 0;
/* magic offset: (first) kernel filename */
memset(&newboot[0x1f1], ' ', 11);
while (opts->kernel.kernel[i] && opts->kernel.kernel[i] != '.')
{
if (i < 8)
newboot[0x1f1+i] = toupper(opts->kernel.kernel[i]);
i++;
}
if (opts->kernel.kernel[i] == '.')
{
/* copy extension */
int j = 0;
i++;
while (opts->kernel.kernel[i+j] && j < 3)
{
newboot[0x1f9+j] = toupper(opts->kernel.kernel[i+j]);
j++;
}
}
}

This commit contains a number of changes:

1. int86x gets and sets struct SREGS members ds and es

2. int86x patches itself (SMC) using a cs: segment override prefix,
as ds may no longer equal cs.

3. int86x interrupt number is %7 rather than %5

4. int86x assembly part doesn't push and pop ds, it is handled by
the compiler instead (in practice it puts a push ss \ pop ds at the
end of the function to restore the near data segment).

5. int86 is implemented by calling int86x (with ds = es = 0)

6. findfirst, int2526readwrite, fat32readwrite also changed to use
int86x because they need to set ds. This used to be implied as the
same ds that the compiler already used by default.

7. Finally, haveLBA changed to set ds to 40h.

The inline assembly constraints for gcc-ia16 are documented in
https://gitlab.com/tkchia/gcc-ia16/-/blob/ca893320926dc93552390b892a202e9373d040c0/gcc/doc/md.texi#L2379
@ecm-pushbx ecm-pushbx changed the title sys.c: in _dos_findfirst set DTA rather than copying from PSP:80h sys.c: in _dos_findfirst set DTA rather than copying from PSP:80h, and work around Xi8088 ROM-BIOS bug (13.41 ds=40h) Oct 10, 2025
@ecm-pushbx
Copy link
Contributor Author

sys.c: work around Xi8088 ROM-BIOS bug for int 13.41 #156

This commit contains a number of changes:

  1. int86x gets and sets struct SREGS members ds and es

  2. int86x patches itself (SMC) using a cs: segment override prefix,
    as ds may no longer equal cs.

  3. int86x interrupt number is %7 rather than %5

  4. int86x assembly part doesn't push and pop ds, it is handled by
    the compiler instead (in practice it puts a push ss \ pop ds at the
    end of the function to restore the near data segment).

  5. int86 is implemented by calling int86x (with ds = es = 0)

  6. findfirst, int2526readwrite, fat32readwrite also changed to use
    int86x because they need to set ds. This used to be implied as the
    same ds that the compiler already used by default.

  7. Finally, haveLBA changed to set ds to 40h.

The inline assembly constraints for gcc-ia16 are documented in
https://gitlab.com/tkchia/gcc-ia16/-/blob/ca893320926dc93552390b892a202e9373d040c0/gcc/doc/md.texi#L2379

@ecm-pushbx
Copy link
Contributor Author

Testing that int 13.41 runs with ds = 40h as desired, with drive E: as a local FAT32 drive on dosemu2:

C:\>ldebug /p sys e: /bootonly
-bp at ptr ri13p when ah == 41
-g
Hit permanent breakpoint 00
AX=4100 BX=55AA CX=FCFA DX=FE80 SP=F860 BP=F86C SI=F89A DI=F86A
DS=0040 ES=4860 SS=2975 CS=F000 IP=F115 NV UP DI NG NZ NA PO NC
F000:F115 F4                hlt
F000:F116 F4                hlt
F000:F117 F4                hlt
F000:F118 F4                hlt
F000:F119 F4                hlt
F000:F11A F4                hlt
F000:F11B F4                hlt
F000:F11C F4                hlt
F000:F11D F4                hlt
F000:F11E F4                hlt
F000:F11F F4                hlt
F000:F120 F4                hlt
F000:F121 F4                hlt
F000:F122 F4                hlt
F000:F123 F4                hlt
F000:F124 F4                hlt
Reached limit of repeating disassembly.
-
System transferred.


Program terminated normally (0000)
-q
C:\>

@ecm-pushbx
Copy link
Contributor Author

Tested the OpenWatcom build a bit too.

@ecm-pushbx
Copy link
Contributor Author

Any comments on this?

@boeckmann
Copy link
Contributor

imported into https://github.com/SvarDOS/sys

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

Successfully merging this pull request may close these issues.

2 participants