\cfg{chapter}{Section}

\cfg{text-filename}{ldos.txt}
\cfg{text-chapter-numeric}{true}
\cfg{text-indent-preamble}{false}
\cfg{text-quotes}{"}{"}
\cfg{text-indent}{4}
\cfg{text-width}{72}

\cfg{html-chapter-numeric}{true}
\cfg{html-suppress-address}{true}
\cfg{html-single-filename}{ldos.htm}
\cfg{html-leaf-level}{0}
\cfg{html-template-fragment}{%k}{%b}
\cfg{html-head-end}{<meta name="viewport" content="width=device-width, initial-scale=1.0">}
\cfg{html-leaf-contains-contents}{true}
\cfg{html-heading-hashtag-links}{true}

\cfg{pdf-filename}{ldos.pdf}

\cfg{ps-filename}{ldos.ps}

\cfg{info-filename}{ldos.info}

\cfg{chm-filename}{ldos.chm}

\cfg{winhelp-filename}{ldos.hlp}

\cfg{man-filename}{ldos.7}
\cfg{man-identity}{ldos}{7}{2026}{}{E. C. Masloch}

\title lDOS kernel manual

\copyright 2025--2026 by E. C. Masloch.
Usage of the works is permitted provided that this
instrument is retained with the works, so that any entity
that uses the works is notified of this instrument.
DISCLAIMER: THE WORKS ARE WITHOUT WARRANTY.

This document has been compiled on \date{%Y-%m-%d}.


\C{building} Building the lDOS kernel

To build only the kernel and sharer, the following tools are needed:

\b bash shell

\b GNU make, or compatible

\b perl to process comload.lst listing file

\b gcc to compile sumspace tool

\b sumspace tool (source text shipped in repo)

\b Netwide Assembler, a recent version needed (at least v2.15)

\b dosemu2 to run DOS tools

\b WarpLink linker (DOS tool, public domain)

\b x2b2 tool (DOS tool, public domain)

\b comtoexe tool (DOS tool, MIT license)

\b lzexe tool (DOS tool, MIT license)

The DOS tools have to be found in the DOS path.


The following components are expected in sister directories to the repo:

\b lmacros

\b ldosboot

\b scanptab

\b kernwrap

\b patchini (must be built separately using the mak.sh, with gcc-ia16,
or provided in binary form)

\b instsect (must be built separately using this repo's makinst.sh)

\b inicomp (if to use compression support),
also needs one of the compression tools:

\lcont{

\b brieflz (blzpack)

\b lz4

\b snappy (snzip)

\b exomizer

\b x-compressor

\b heatshrink

\b lzip

\b lzop

\b lzsa -- default choice, one of the fastest depackers

\b apultra

\b bzpack

\b lzexedat

}


\C{starting} Starting the lDOS kernel

The lDOS current release build includes four different kernel files
in the \cw{bin/} subdirectory:
\cw{ldos.com}, \cw{ldos.sys}, \cw{ldospak.com}, and \cw{ldospak.sys}.
Any single one of these four files contains the complete kernel.

The \cw{.com} files are called iniload variants, as they are wrapped
in the lDOS iniload.asm (initial loader) stage.
They are valid DOS MZ application executables
and can be loaded as a number
of different kernel formats.

The \cw{.sys} files are called drload variants, from the stage
named drload.asm (originally created for the lDOS flavour
of the Enhanced DR-DOS kernel).
They are only valid to be loaded as FreeDOS kernel
(typically named \cw{kernel.sys})
or as EDR-DOS kernel
(typically named \cw{drbio.sys}).
The advantage is that they are smaller than the iniload variants.

The \cw{ldos} files are uncompressed.
The advantage is faster load time and being able to patch the kernel image.

The \cw{ldospak} files are compressed.
The advantage is, again, the smaller file size.


\H{booting} Booting lDOS

The lDOS kernel can boot off diskette drives (fda, fdb, fdc, fdd)
or FAT16 or FAT12 partitions on MBR-partitioned hard disk drives.
Both primary and logical partitions are supported.

Loading off logical partitions may require loaders that support this
at all and a correct (unit absolute) value for hidden sectors,
either hardcoded into the boot sector loader or automatically
detected at boot time. ldosmbr's altmbr, ldosboot boot.asm, and
lDebug all do support this.

The default drive at boot time may be any drive that matches
the boot partition, that is it may be different than A: or C:.
If the exact partition cannot be identified from
the load unit plus hidden sectors,
then the first drive
that is logged in on the same unit
is selected as the default drive.
If no such drive exists,
then either drive A: or the first hard disk drive (C:, D:, or E:)
is selected, depending on whether the load unit is < 128 or >= 128.
The configuration files are searched for in the root directory
of the default drive unless the kernel command line specifies
pathnames that include a drive specification.


\H{instsect} Installing boot sector loader using INSTSECT

The recommended choice is to install a boot sector loader
using the instsect application.
This application is found both in \cw{instsect.com} and
in the COMLOADER multi-executable tool which is embedded in \cw{ldos.com},
using the command program name \cw{instsect}.

The default filename for instsect's loaders is \cw{ldos.com}.
Note that the loaders use the lDOS load protocol.
Trying to load \cw{ldos.sys} or \cw{ldospak.sys} using these loaders
will fail with a check 'V'alue error (letter \cq{V} displayed at boot time).

The instsect online help can be accessed using the \cw{/?} switch.
Redirect to a file or to a tool like \cq{more} to read all of it.


\C{fs} Supported file systems

lDOS currently supports the following file systems:

\b Diskette drives (up to 4)

\b MBR-partitioned hard disks

\b CHS or LBA access on int 13h units

\b Primary partitions

\b Logical partitions (in extended partitions of type 5, 0Fh, or 85h)

\b FAT12 or FAT16 file systems

\b Partition types 0Eh (FAT16 LBA) and 0Fh (Extended LBA)
only supported if HDD is accessed using LBA extensions

\b Cluster sizes that are a power of two
between 1 and 64 sectors

\b Cluster size of 128 sectors (MSW NT extension)

\b Cluster size of 256 sectors (Enhanced DR-DOS extension)

\b Int 13h unit must use a sector size of 512 Bytes.

\b Kernel is LFN aware, that is it doesn't mistake LFNs
for volume label entries. It doesn't support LFNs.

\b FAT32 and FAT+ are not supported.
(lDOS iniload can boot off a FAT32 drive but
it won't be logged in and supported by the kernel after boot time.)


\C{config} lDOS configuration

There are four inputs to the lDOS configuration:

\b lDOS iniload query patch site, modified using \cw{patldos query}

\b lCFG block, modified using \cw{patldos}

\b lDOS kernel command line, can be passed using bootable lDebug to chainload lDOS

\b Configuration file


\H{config-querypatch} Query patch

The query patch site determines whether the initial loader uses
CHS or LBA access, and whether it queries the CHS geometry
using int 13h function 08h.
This is accessed using the \cw{patldos} tool using the \cw{query} keyword.
(The \cw{patldos} tool is included in the \cw{ldos.com} COMLOADER.
The \cw{patldos} tool is available
as an 8086 assembly language DOS program
or as a portable C language program.)

The query patch site is not passed along to the lDOS kernel yet.


\S{config-querypatch-patldos} Supported \cw{patldos query} values

\c Usage: patldos [QUERY [ldos.com [DISKETTE|HARDDISK [number]]]]
\c
\c Supported query patch flags:
\c  01h: Force CHS
\c  02h: Force LBA
\c  04h: No query geometry
\c  08h: Force single sector reads
\c  40h: Do not re-check (TestWrit)
\c  80h: Apply to LDP (lDebug)

Default is 0 for both unit types.
The flags are detailed more
\W{https://pushbx.org/ecm/doc/ldosboot.htm#protocol-sector-iniload-patch}{in the lDOS boot manual}.


\S{config-patldos-number} Parsing of numbers in \cw{patldos}

Numbers can be specified in three bases:

\dt Default

\dd Decimal

\dt \cw{0x} prefix or \cw{h} suffix

\dd Hexadecimal

\dt \cw{0b} prefix or \cw{b} suffix

\dd Binary

A number can be immediately preceded by a plus sign or minus sign.
A plus sign indicates the number given is treated
as an OR mask (set these bits).
Likewise, a minus sign indicates that it should be treated
as an inverted AND mask (clear these bits).

There may be multiple numbers specified wherever \cw{patldos}
parses a number.
They need to be separated by blanks.
Only the very first number may lack both a plus and minus sign.
If such a number occurs, its value replaces the entire configuration choice.
If the first number given does have a plus or minus,
some bits of the prior choice read from the kernel file
may be retained,
depending on the given masks.


\H{config-lcfg} lCFG block

The lCFG block currently contains five configuration choices.
All of them can be accessed using the \cw{patldos} tool.
(The \cw{patldos} tool is included in the \cw{ldos.com} COMLOADER.
The \cw{patldos} tool is available
as an 8086 assembly language DOS program
or as a portable C language program.)
All numbers given as the last parameters
to \cw{patldos} are parsed as indicated in \k{config-patldos-number}.

The following configuratiom choices are used
by the default lDOS build:

First, the inicomp depack progress display choice.
This is only included in ldospak,
ie the build in which the kernel image is compressed.
This allows to choose none, dots, percentage, bar, or bar with percentage.
This is accessed using the \cw{patldos} tool
using the \cw{progress} keyword.
Supported values are displayed by running without parameters
after the \cw{progress} keyword.

Second, the debugger detection choice.
This indicates conditions for detecting a resident debugger
in order to avoid overwriting its int 1 and int 3 handlers.
This is accessed using the \cw{patldos} tool
using the \cw{debug} keyword.
Supported values are displayed by running without parameters
after the \cw{debug} keyword.

Third, the verbose flags choice.
This specifies what informational messages to display during system init.
This is accessed using the \cw{patldos} tool
using the \cw{verbose} keyword.
Supported values are displayed by running without parameters
after the \cw{verbose} keyword.

Fourth, the partition scan mode choice.
This specifies several options on which partitions to log in
and in what order.
This is accessed using the \cw{patldos} tool
using the \cw{scanmode} keyword.
Supported values are displayed by running without parameters
after the \cw{scanmode} keyword.

Fifth, the halt flags choice.
This specifies what conditions not to halt on.
If a halt flag is set, then the condition causes a warning message
but does not halt the system.
If a halt flag is clear, the condition displays the message and halts.
This is accessed using the \cw{patldos} tool
using the \cw{haltflag} keyword.
Supported values are displayed by running without parameters
after the \cw{haltflag} keyword.


\S{config-lcfg-pro} Supported \cw{patldos progress} values

\c Usage: patldos [PROGRESS [ldos.com [APP|DEV|BOOT [number]]]]
\c
\c Supported progress choices:
\c      0: None
\c      1: Dots
\c      2: Percentage
\c      3: Bar
\c      4: Bar with percentage

Default is 1.

There is a special flag, with value 16.
This is only supported for APP and DEVICE modes.
If set, then the selected progress choice is written to stdout
even when stdout is redirected to a file.
If clear, using a redirected stdout forces the progress display disabled.
(As the lDOS kernel inicomp payload only supports boot mode,
this flag is never supported by the kernel.)


\S{config-lcfg-deb} Supported \cw{patldos debug} values

\c Usage: patldos [DEBUG [ldos.com [number]]]
\c
\c Supported flags:
\c      1: Check
\c      2: Assume
\c      4: Check only valid
\c      8: Check only IISP

Default is 0.

\S{config-lcfg-ver} Supported \cw{patldos verbose} values

\c Usage: patldos [VERBOSE [ldos.com [number]]]
\c
\c Supported flags:
\c      1: Intro line
\c      2: XMS use
\c      4: CDS writes

Default is 1.

\S{config-lcfg-sca} Supported \cw{patldos scanmode} values

\c Usage: patldos [SCANMODE [ldos.com [number]]]
\c
\c Supported flags:
\c      1|2: Ext5 setting
\c      4|8: Ext15 setting
\c     16|32: Ext85h setting
\c    40h=   64: Ignore subsequent nested
\c    80h=  128: Ignore subsequent logical
\c   100h=  256: Ignore subsequent primary
\c   200h=  512: Traditional order logical
\c   400h= 1024: Active priority
\c   800h= 2048: Subsequent primary after
\c  2000h= 8192: Ignore FAT32
\c  4000h=16384: Ignore LBA
\c  8000h=32768: DLA sort disable
\c Supported ext settings:
\c  0 = follow all
\c  1 = ignore all
\c  2 = follow first of any ext
\c  3 = follow first of this type

Default is 0.


\S{config-lcfg-halt} Supported \cw{patldos haltflag} values

\c Usage: patldos [HALTFLAG [ldos.com [number]]]
\c
\c Supported flags:
\c      1: Don't halt on TAGCRASH
\c      2: Don't halt on MCB corrupted
\c      4: Don't halt on HMCB alloc corrupted
\c      8: Don't halt on HMCB free corrupted

Default is 0Ch.


\H{config-cmdline} Kernel command line

The kernel command line is a text string of up to 255 bytes
that can be passed to the kernel from the prior loader.
Bootable lDebug allows to pass a command line when loading
a kernel using the RxDOS.2, RxDOS.3, lDOS, FreeDOS, or EDR-DOS load protocols.
(The latter two need to enable this using a \cw{CMDLINE=1} parameter.)

The commands of the command line are separated by semicolons.
A semicolon immediately following another semicolon is parsed
as an escaped semicolon. The following command names are recognised:

\dt CONFIG

\dd Highest priority configuration file override.
This file is tried first.
Default is empty.

\dt ALTCONFIG

\dd Second configuration file override.
This file is tried second.
Default is \cq{ldos.ini}.

\dt OLDCONFIG

\dd Third configuration file override.
This file is tried last.
Default is \cq{config.sys}.

\dt PREPEND

\dd Prepend the following line to the configuration file contents.

\dt APPEND

\dd Append the following line to the configuration file contents.

\dt CHECKDEBUGGER

\dd Modify check debugger value from lCFG block.
Refer to \k{config-lcfg-deb} for supported values.
Numbers may be prepended by \cq{+} plus sign to OR number into the variable,
or by \cq{-} minus sign to AND the bitwise NOT of the number.
Otherwise the number will rewrite the entire variable to the number.
Numbers default to decimal format,
unless leading \cq{0x} or trailing \cq{h} is specified.
Multiple numbers may be specified separated by commas.

\dt VERBOSE

\dd Modify verbose value from lCFG block.
Refer to \k{config-lcfg-ver} for supported values.
Numbers may be prepended by \cq{+} plus sign to OR number into the variable,
or by \cq{-} minus sign to AND the bitwise NOT of the number.
Otherwise the number will rewrite the entire variable to the number.
Numbers default to decimal format,
unless leading \cq{0x} or trailing \cq{h} is specified.
Multiple numbers may be specified separated by commas.

\dt SCANMODE

\dd Modify scan mode value from lCFG block.
Refer to \k{config-lcfg-sca} for supported values.
Numbers may be prepended by \cq{+} plus sign to OR number into the variable,
or by \cq{-} minus sign to AND the bitwise NOT of the number.
Otherwise the number will rewrite the entire variable to the number.
Numbers default to decimal format,
unless leading \cq{0x} or trailing \cq{h} is specified.
Multiple numbers may be specified separated by commas.

\dt HALTFLAG

\dd Modify halt flag value from lCFG block.
Refer to \k{config-lcfg-halt} for supported values.
Numbers may be prepended by \cq{+} plus sign to OR number into the variable,
or by \cq{-} minus sign to AND the bitwise NOT of the number.
Otherwise the number will rewrite the entire variable to the number.
Numbers default to decimal format,
unless leading \cq{0x} or trailing \cq{h} is specified.
Multiple numbers may be specified separated by commas.

\dt \cq{.} (dot)

\dd Command ignored, possibly used for future optional extensions.


\H{config-file} Configuration file

If a configuration file is found, its length is checked.
The length should not exceed 56 KiB.
Then a buffer is allocated and the entire file is read.
Too long file contents may be truncated.
The command line PREPEND and APPEND lines
are also stored in the buffer.

Aside all the usual MS-DOS v4 level configuration directives,
some additional directives are supported:

\dt DEVICEHIGH

\dd Like DEVICE but attempt to load into the UMA

\dt INSTALLHIGH

\dd Like INSTALL but attempt to load into the UMA

\dt INSTALLLAST, INSTALLLASTHIGH

\dd Like INSTALL, INSTALLHIGH but after final DOSDATA and DOSCODE relocation

\dt INSTALLMID, INSTALLMIDHIGH

\dd Like INSTALL, INSTALLHIGH but before final DOSDATA relocation,
after any DEVICE directive has been processed.
Same as default INSTALL (absent COMPAT settings to change INSTALL order).

\dt INSTALLFIRST, INSTALLFIRSTHIGH

\dd Like INSTALL, INSTALLHIGH but during the pass
that processes DEVICE directives.

\dt SHELLHIGH

\dd Like SHELL but attempt to load into the UMA

\dt COMPAT

\dd List comma-separated compatibility options.
The following options are recognised:

\lcont{

\dt (NO)ALTAH

\dd Control allocation of a compatible
ALTAH (CON device driver look-ahead buffer)
that should be found at the segmented address 70h:61Bh.

\dt (NO)DOSDATAFIRST

\dd Control relocation of DOSDATA segment first,
before loading any device drivers.
This means the segment will be allocated in the Low Memory Area.

\dt (NO)DOSDATAEARLY

\dd Control relocation of DOSDATA segment early,
after any device driver.
The segment is relocated after the first device driver load
that provides DOS with a sufficiently large (ca 6 KiB)
Upper Memory Block.
If no such UMB is provided at all
then the DOSDATA segment is eventually relocated into the
Low Memory Area at the default end relocate time.

\dt (NO)BOUNCEHMACHS

\dd Control bouncing CHS disk accesses involving the HMA
through the Low Memory Area (DOSENTRY) disk sector buffer.
This slows down the access but may be required
if the access won't work in the HMA.

\dt (NO)BOUNCEHMALBA

\dd Control bouncing LBA disk accesses involving the HMA
through the Low Memory Area (DOSENTRY) disk sector buffer.
This slows down the access but may be required
if the access won't work in the HMA.
(Appears to be needed for qemu.)

\dt AUTOBOUNCEHMACHS

\dd Enable automatic determination of bouncing CHS disk access
involving the HMA.
This is done by reading all DOS-internal CHS accessed nonremovable drives'
boot sectors to the HMA shortly after it is allocated,
but before DOSCODE is installed into it.
If any of them are written to an A20-wrapped address
into the disk sector in the DOSENTRY section
which is in the Low Memory Area,
bouncing is enabled for all CHS accesses.
A message indicating the first drive that needs this is then displayed.
Specifying either BOUNCEHMACHS or NOBOUNCEHMACHS
disables this automatic detection.

\dt AUTOBOUNCEHMALBA

\dd As above but for LBA accessed nonremovable drives.

\dt (NO)BOUNCEUMACHS

\dd Control bouncing CHS disk accesses involving the UMA, or HMA.
If enabled, all accesses to the UMA (typically starting at segment A000h)
and also the HMA will be bounced through the LMA (DOSENTRY) disk sector buffer.
If disabled, UMA accesses are not bounced but HMA accesses still may be.

\dt (NO)BOUNCEANYCHS

\dd If enabled, bounce any CHS disk access
through the DOSENTRY disk sector buffer.
If disabled, LMA accesses are not bounced but UMA and HMA accesses still may be.

\dt (NO)BOUNCEUMALBA

\dt (NO)BOUNCEANYLBA

\dd As above but for LBA accessed drives.

\dt (NO)HIDEDOSENTRY

\dd Controls hiding of the first MCB, which is for the DOSENTRY segment.
This MCB typically is located at segment 60h.
Some programs such as FreeDOS MEM with its /D switch
may not expect the entry segment
and its device driver headers to appear in an MCB.
If this is enabled, the first MCB in the DOS list of lists
is changed to point past the DOSENTRY MCB.

\dt (NO)HIDEDOSDATAFIRST

\dd Controls hiding of the DOSDATA MCB.
This only takes effect if DOSDATAFIRST is enabled.
The DOS list of lists first MCB field is changed to
point past the final DOSDATA MCB after the relocation, then.
This implies that the DOSENTRY MCB is hidden as well.
The ALTAH MCB may also be hidden due to this,
if the ALTAH option is enabled.

\dt (NO)COLLECTALLMCBS

\dd Controls coalescing of all free MCBs during memory allocation.
Default is enabled.
When disabled, only free candidate MCBs are grown within
the Allocate MCB main loop, avoiding the separate loop.

\dt (NO)COLLECTFREEMCB

\dd Controls coalescing of free MCBs
behind the freed MCB during memory deallocation.
Default is disabled.
EDR-DOS is known to act like COLLECTFREEMCB.

\dt (NO)INSTALLASLAST

\dd If enabled, INSTALL acts like INSTALLLAST.
Default is disabled
(so that INSTALL acts like INSTALLFIRST or INSTALLMID).

\dt (NO)INSTALLASFIRST

\dd If enabled,
and INSTALLASLAST is not enabled,
INSTALL acts like INSTALLFIRST.
Default is disabled
(so that INSTALL acts like INSTALLLAST or INSTALLMID).

}
