Table of Contents

Late September work

2024-09-29

instsect

The instsect application now supports double quote marks around the /SG= string, so that copying the output of the application to specify as /SG= is supported. However, the closing quote mark must end the entire string, it is not supported to toggle quoted and unquoted parts arbitrarily.

cntlines

lDebug

Other than these two changes I also prepared a comparison of the 2008-02-27 FreeDOS Debug/X v1.13 (original base for lDebug) to the 2010-10-24 initial commit of lDebug and the 2024-09-21 current revision of lDebug. This comparison displays statistics on the source using the cntlines tool. I also prepared a spreadsheet with a few charts, using Google Sheets, depicting some of the cntlines measurements. (If the charts don't display in that link, you may want to try dropping the /htmlview suffix.)

lDOS boot FAT32+FSIBOOT

While reviewing the lDOS FAT32 loader to prepare for the upcoming FSIBOOT5 revision of its two-stage protocol, I found that I could save a byte in the FSIBOOT stage's byte-granular file size check. The idea was to re-arrange the registers used so that rather than test dl, 15 (a 3-byte instruction) I could use test al, 15 (a 2-byte instruction). During this work I also discovered a way to replace mov bx, 0FFFFh by xchg ax, cx and dec ax. Despite this, the final result only left one byte free, over the prior revision with zero bytes free.

When I went to test the new implementation, I prepared several files on a 126 MiB FAT32 file system. One was just the lDebug lcdebugx.com executable, clocking in at 101_376 Bytes. Another was lcdxeld.com, the same debugger executable with extpak.eld appended, at 238_785 Bytes. The third was the executable with 1000 KiB of random data appended (1_125_376 Bytes), named lcdx1m.com. The final file was the executable again, called large.com, but with its directory entry hacked so some of the FAT+ size bits were nonzero, suggesting a size larger than 4 GiB.

The test loaders were created using eg instsect C: /B=1.bin /F=lcdebugx.com and loaded from bootable lDebug using boot protocol chain hda1/1.bin. A g 7CFF command skipped right to where the first boot loader stage has loaded (and is transferring control to) the FSIBOOT stage.

I successfully tested all four cases. However, during the testing I figured that there may be a case that would fail. Indeed, preparing check.com (as a copy of lcdx1m.com) and truncating it to a file size of 1_048_575 Bytes, or F_FFFFh Bytes, or 1 MiB minus 1 Byte, resulted in an "E" error return of the loader, indicating Not "E"nough File Data. I had found that with file sizes >= 0F_FFF1h and ⇐ 0F_FFFFh the large file case wasn't taken, but the detected 0FFFFh full paragraphs (rounding down) would be rounded up after the "check enough" call, overflowing back to zero. This would immediately end the load after the first file sector had been loaded, then find that it didn't have enough data loaded, resulting in the "E" error. This bug was present in the code prior to this Sunday already.

With only one byte to spare it seemed difficult to change the inc bx to a saturating increment, so as to keep the 0FFFFh maximum value when the file size fell in this range. However, I did manage to do it by re-arranging some things. But the test al, 15 is replaced by test cl, 15 in this. The FSIBOOT stage had zero bytes free again. The key insights were:

  1. Load file size into bx to begin with because for check_enough it must be in bx,
  2. Skip check_enough call for .large_file case because it couldn't possibly fail,
  3. If the inc bx (rounding up paragraphs) results in zero (overflowed) then fall through into the .large_file case.

With all memory accesses so close in this revision, we then could save a byte by temporarily changing ds.