blog:pushbx:2025:1020_ldos_boot_enhancements_in_mid_october
Table of Contents
lDOS boot enhancements in mid October
2025-10-19
lDOS boot (non-experimental)
Add a list of the error condition letters used by boot.asm and boot32.asm to the manual.
lDOS boot (experimental)
- Display the +3 for the number of bytes available before ms7_entry if a transfer to the error_outofmemory label is included.
- Optimisation: Discard LBA packet by using
add sp, [si + lpSize](as this instruction only takes 2 bytes). - Use dot-terminated error messages. The second error message, listing the specific error, is re-used by a
dec siandcallto actually display the dot, whereas the first message (the common prefix) uses the dot only as a terminator. - Zero the ah register for int 16h function 00h by using
cbwwith al containing 2Eh, the dot terminator of the error messages. - In read_sector.int13_set_lpcount always set
byte [si + lpCount]to 1 before calling int 13h function 02h or 42h. For CHS access we make sure to point si at unclaimed stack space. - Always try sector segment read if the normal read failed, without checking for the error code 09h.
- Replace cwd by xor to zero dx when loading the FAT for FAT12. The register use changed so that ax is no longer known to be zero (or, indeed, < 8000h) at this point.
- Swap operations so cwd can be used to zero dx again. Instead of ax = 0000h this uses ax ⇐ 0FF5h, and prepares dx before using ax to check whether the FAT load is needed at all.
- Check for two overflows: A build time check that payload.actual_end + maximum sector size cannot overflow FFFFh paragraphs, and a run time check that rounded up payload.actual_end plus cs doesn't overflow. (This is only possible with a large payload and/or when the Low Memory Area extends higher than usual.)
- Update a comment in multi_sector_read to note that al is always <= 127 when entered after a successful LBA sector read call.
- Update read_sector comment on not checking for error code 09h to attempt the sector segment read.
- Fix: The read_sector.dx_ax_cx_lba_to_chs return patch needs to be reset differently now, E8h (near immediate call) rather than B8h (mov ax immediate). The patch label now includes the hexadecimal opcode value that it should be reset to.
- Share .lba_done and .done code by inserting a __TEST_IMM16 (incorrectly stated as a "test imm8" in the changeset message) to have the sector segment code skip over the
add spinstruction, saving 1 byte as one fewer short jump is used. - Before the read_sector call that reads a FAT sector (for FAT16 or FAT32) use es to set bx, instead of re-reading the FAT buffer segment from the lsvFATSeg variable.
- Share part of the skip next cluster/sector loop with the load next loop. As it says in the changeset message: "The file loop code can be re-used partially, as the lsvLoadSeg check will simply be tripped again on every iteration through what was originally the skip loop."
- Put a better check for late multi-sector loader initialisation into the end+32 part. This removes the need for a sector size >= 512 bytes for this check. It also eliminates the end+64 part after two sectors were read.
- For the subtraction that calculates how many paragraphs to relocate down, do not include the subtraction twice. Rather, for the usual code run a compare instead, then if relocation is needed fall through into the subtraction previously used only for the unusual code path. Saves a short jump, 2 bytes.
- Bugfix: As of the very first revision of the multi-sector loader, reads that crossed a 64 KiB boundary didn't decrement the counter of remaining reads as needed when calling read_sector to carry out a read. This would break the load if the load file was fragmented and during a read not belonging to the last fragment a 64 KiB boundary was crossed by a single-sector read.
- Merge the prior bugfix into the most recent branch.
- Keep lsvFATSector in the variable rather than using si:di to hold it, and use
es lodswto load from the FAT (for FAT16 and FAT32). - boot.asm _FAT16: Keep lsvFATSector in the variable rather than using di to hold it.
- boot32.asm: Keep lsvFATSector in the variable rather than using si:di to hold it, and use lodsw. After studying the interface I decided to keep the FSIBOOT5 signature for this revision, although I added detection to instsect that calls it FSIBOOT revision "5a".
- boot32.asm: Toggle sense of Carry Flag output of check_clust. This is only used internally by the FSIBOOT stage so doesn't call for a new FSIBOOT revision either.
- boot32.asm: Introduce the _FREE_PARA_LIMIT define to limit lDOS load to 4 KiB.
- Optimisation: Now that di is no longer used to hold part of the currently loaded FAT sector, re-use it in the multi-sector loader to replace the ldmAmount variable.
- Extract the check_end3_loaded function, and put a stc behind the end+32 limit.
- Spaghettify and add a call to check_end3_loaded to skipped_all_multi. I closed this branch later as it wasn't desirable to only do this check after loading at least 1 non-terminal file fragment.
- Spaghettify once and twice and add a call to check_end3_loaded to the multi_sector_read function. As described in the comment, the branch after this check is only enabled upon entry to skipped_all_multi so as to avoid incorrectly branching after the FAT load that may be needed on FAT12. When skipped_all_multi is entered, all subsequent calls to multi_sector_read are known to be for the load file data, so comparing the resulting bx => behind loaded data is then valid.
- Display the distance encoded in the late_progress_init branch, and check that it is ⇐ 127. (It is, but narrowly.)
- Add a transfer jump to late_progress_init before end2 if there's 3 or more bytes free there. This jump is placed directly after the multi_sector_read code so that the distance of the check_end3_loaded branch won't overflow 127 bytes (the short jump forwards distance limit).
- Optimise skipped_all_multi by sharing the code that sets the ldmSector variable.
- testboot.asm: Check method 2 list length (⇐ 32) and displacement limits (below 62 except for the -1 and -2 sentinel values).
- testboot.asm: Re-order method 2 list and expand it to make use of the entire range.
- testboot.asm: Add define _EXTENDED to fill the method 2 sector completely, with new stack dump items SG to SR. This requires encoding the halved displacement instead of the full one, costing 2 bytes of code to decode the displacement. (Without this encoding change, some of the higher stack items would overflow the 6-bit displacement field.)
- Drop obsolete patch comment on read_sector.dx_ax_cx_lba_to_chs (from back when the patch always had to restore B8h).
- Optimisation: Calculate FAT12 byte offset in si already, avoids having to move it there later.
- Same doc patch as for ldosboot (non-experimental).
- Drop load_next_sect completely, handle the entire single-sector loader logic in the loop that at first skips the already-loaded prefix.
- Drop some now unneeded branches. Make skipped_all_continue directly call check_end3_loaded, then continue on to loadorskip_next_sector. (If neither _MULTISECTOR nor _ADDPROGRESS are enabled, skipped_all_continue is an equate for loadorskip_next_sector.) The branches to loaded_all.2stack from the end+32 part are also dropped.
- Fix build with several defines:
- boot.asm and boot32.asm: Mark magic code used by instsect /4 PREFIX option.
- Correct a comment, >> right shift operator has a lower precedence than + addition.
lDebug and lDOS kernel
No change, just an empty changeset to rebuild with new instsect revision, for both lDebug and the lDOS kernel.
instsect
- Introduce a third parameter to fsi_revision mmacro for a subrevision marker.
- Add FSIBOOT revision 5a for updated boot32.asm loader, detected using a code snippet.
- Add comment on FSIBOOT revision 5a using the same signature as revision 5.
- Add the /4 PREFIX option to patch lDOS boot sector loaders so they will load only up to segment 300h rather than 7A0h.
- Fix the help message line for /4 PREFIX option.
- fsiboot.mac: Update attribution year.
amdpd
- Pass -q and -quiet options to the dosemu2 command used for linking.
Blog
The other day I finished a blog post reviewing the initial commit of lDOS boot's iniload, on 2017-10-03, as well as the updates to it within the same month.
You could leave a comment if you were logged in.
blog/pushbx/2025/1020_ldos_boot_enhancements_in_mid_october.txt · Last modified: by ecm
