Early October updates
MSDebug
lDOS kernel
bootimg/partdisk
ACEGALS
lDOS boot (experimental)
The recent changes to the lDOS boot loaders was kicked off by a SvarDOS report on loading their kernel off a 360 KiB diskette. Reportedly, using the FreeDOS-based boot sector loader took more than 28s to load the kernel. In the report, an alternative loader was presented which doesn't use the file system but rather loads the kernel from the file system reserved sectors, reducing the time spent to 6s. The speedup is primarily from reading using multi-sector calls, allowing to read up to a full track (S coordinate 1 to amount of CHS-sectors) using a single call to int 13h.
I suggested that the lDOS initial loader could be modified to use an optional multi-sector loader, along with an lDOS boot sector loader modified to load only the first 4 KiB of the initial loader stage. As it took shape, testing indicated a speed up to 8s - not quite as fast as the reserved sectors load but a good competitor. And it is no less generic than the lDOS iniload basis, allowing to boot as an lDOS / RxDOS.3 kernel, a FreeDOS or Enhanced DR-DOS kernel, an MS-DOS v7 kernel, an IBM-DOS or MS-DOS v6 kernel, or a Multiboot v1 or Multiboot v2 kernel.
Eventually I adapted the multi-sector loader so it can be used for any load protocol, if the sector size check indicates at least 512 bytes per sector. This is accomplished by putting a relatively small check into the single-sector load loop after it has loaded at least 2 sectors, fitting into the 64 bytes space that 2 sectors take up with the theoretical minimum sector size of 32 bytes. If the sector size is detected as 512 bytes or more, then this code knows that at least 1536 + 512 + 512 bytes have been loaded, so the multi-sector loaders (both CHS and LBA) are resident at this point.
Some unrelated optimisations were applied, most of them related to freeing enough space for the new features. Further, a bug of expecting ah to be unchanged after an int 10h function 0Eh call was fixed in the boot sector loaders. The FAT12 loader also got an option to load FAT sectors on demand rather than loading the entire FAT, but this is ill-advised at least for 360 KiB diskettes or smaller (as these only have 1 or 2 sectors per FAT to begin with).
Individual changes:
-
-
-
-
-
boot.asm:
Introduce _FREE_PARA_LIMIT to load less from the iniload file than there's space below 7A00h. (Without this option, up to 5A00h bytes are loaded to 2000h, corresponding to 45 sectors at 512 Bytes per sector.)
-
Add single-sector fallback if multi-sector loader encounters a failure after repeated attempts. This sets a flag so all subsequent reads are done one sector at a time. It doesn't restore the context of the traditional loader however, opting to observe the new flag within the loop of the multi-sector loader.
-
Drop most of the .eoc code in the multi-sector loader loop. The file is always either too short or terminates in a bad cluster if this part is reached, so no attempt to read the remaining fragment is needed.
-
-
-
-
-
-
-
-
-
Add an LBA multi-sector loader before end3. The end3 label is a new invention, it is expected to live no later than at the 4 KiB offset of the file. Unlike end and end2, end3 isn't padded to fill the 4 KiB reserved space however.
-
-
-
Optimise multi_sector_read.lbapatch
to drop the test imm16 instruction, patching the entire three bytes to create a near jump instruction rather than only the one byte of the opcode.
-
-
-
-
-
-
-
-
-
-
-
Optimisation,
store ldLoadingSeg in clust_next. This was done in two spots right before calling clust_next, with a change to only set it after the cluster loop (and reload it before the cluster loop rather than for every sector).
-
-
-
Late initialisation of the multi-sector loader if initially there wasn't enough code loaded to init it. This happens after loading the FAT12 (if any) and at least 2 sector loads from the file, so it isn't preferred but can still speed up the remaining load.
Harden,
allow init_memory_multi to not install by having the late init patch in a jump to skipped_all.multipatch rather than to skipped_all_multi. This means if the multi-sector loader is installed it is entered all the same but if not then the single-sector loader can continue to run to completion.
-
-
tractest/convlist.pl
Change from die to print for unknown section or differing group for the same section. (The group can only differ for WarpLink if the class also differs, a different group for the same section+class name is rejected by the linker.)
-
lDebug
-
-
-
-
boot.asm:
Cache a single FAT sector during yy boot read or seek. Dramatically improves the time spent on loading ELDs from the uncompressed extlib.eld library, from a physical 1440 KiB diskette. Details in the changeset message. (As for the question of when ldfFATInvalid is cleared, it is useful to look into boot.asm where query_geometry and initialise_fs are called. The only call to initialise_fs with the flag still clear is for the kernel load, in which case an 8 KiB buffer for the FAT is allocated in the LMA (below the debugger allocation). All other callers set the ldfFATInvalid flag and re-use the auxbuff for loading FAT sectors on demand.)
Add extpak.eld _ALIGNPAGE option so the compressed stream is aligned on a 512-byte boundary and the filebuffer is also 512 bytes in size. This nearly halves the sector reads needed to load an ELD from the compressed extpak.eld library.
-
-
-
-
-
-
ident86
wwwecm scripts
FreeDOS kernel
-
-
-
sys:
Also use ds=40h workaround for int 13h function 41h. Required some more changes because the gcc build didn't include int86x to set the segregs for an interrupt call. And then the int86 calls sometimes expected the default ds to be passed to the interrupt call.
The last two commits aren't merged yet as of the time of this writing.