====== Late mid March work ====== **2024-03-24** This week I worked some on instsect, ldosboot, and lDebug. Some development on Debug/X happened as well ([[https://github.com/Baron-von-Riedesel/DOS-debug/commit/8fe85746999734d3e3e0e945e6bdda0c32228732|1]], [[https://github.com/Baron-von-Riedesel/DOS-debug/commit/b68f9530beef41f816b0096982d290bc6ab7874c|2]]), part of which was in response to my bug reports ([[https://github.com/Baron-von-Riedesel/DOS-debug/issues/13|1]], [[https://github.com/Baron-von-Riedesel/DOS-debug/issues/5|2]]). ===== instsect ===== While using instsect to [[https://stackoverflow.com/questions/78177635/x86-bios-stage-1-boot-code-halting-after-loop-from-interrupt/78179353#78179353|install a stackoverflow user's boot sector loader]] I noticed that it misdetected two filenames in the error messages. This was because their error messages happened to be in allcaps. It turned out to be sufficient in this case [[https://hg.pushbx.org/ecm/instsect/rev/83635a628071|to detect when a blank in either candidate field]] (base name or extension) is followed by a nonblank in the same field, which never occurs for valid filenames. ===== ldosboot ===== The test payload shares the filename detection of instsect. Therefore I [[https://hg.pushbx.org/ecm/ldosboot/rev/d23a1f5d9a6a|picked the blank detection change]] from instsect. ===== lDebug ===== ==== Manual updates ==== Several updates to the manual happened. In particular, [[https://pushbx.org/ecm/doc/ldebug.htm#eldputs|the description of the ELD (multi-purpose) puts handler]] was updated and had the ''puts_ext_next'' entry added. The ELD puts copyoutput and puts getline handlers were added too. During the updates to the manual, I noticed that ''transfer_ext_cx'' did not preserve the flags in the _PM=1 build. This was initially documented as a bug. It happened to be a benign bug though. ==== Dispatch optimisation ==== === LINKCALL === The internal LINKCALL ELD (not loaded and installed like a regular ELD, but behaves like one otherwise) prompted me [[https://hg.pushbx.org/ecm/ldebug/rev/e742319bbd01|to add a new variable]]: ''pm_2_86m_0'' is a word variable that is equal to 2 in Protected Mode and equal to 0 otherwise. (In _PM=0 builds it is always equal to 0, of course.) This simple variable allows to optimise the Protected Mode dependent dispatch, dropping a function call or test instruction as well as a conditional jump. The dispatch can happen either directly for variables, or for code pathes instead by utilising jump tables. The biggest win is likely that we need not run ''pushf'' and ''popf'' instructions any longer, as the dispatch can occur completely using just ''mov'', ''push'',''pop'', or ''lea'' instructions. These never affect the arithmetic status flags. However, the new dispatch does have to use an additional register, usually ''di''. This is a minor disadvantage though. To actually [[https://hg.pushbx.org/ecm/ldebug/rev/1494a5226698|apply this to the link call handlers]], I multiplied the offsets passed in ''bl'' by 2 for the _PM=1 build. In the _PM=0 build they are passed as 0 (entry section), 2 (first code section), or 4 (second code section). In _PM=1 builds they are now passed as 0, 4, or 8. The ''extcall_table'' was re-ordered to accommodate the new offsets. This involves unused padding words between the ''.ret'' entries, and interleaving the references to the selector variables with the references to the segment variables. This enabled the dispatch to not need any addition or multiplication instructions. === Transfer to ELD code section === After the link call handlers in the LINKCALL ELD, [[https://hg.pushbx.org/ecm/ldebug/rev/635733e2dad3|the next dispatch to adjust]] was ''transfer_ext_cx''. This one required a jump table because of how the ''di'' register needs to be preserved but the dispatch needs to push a mode-dependent variable to the stack. I initially pondered a trampoline in the ELD code section that would consist of the instructions ''pop di'' and ''jmp cx''. However, this would make it more difficult to initialise the ELD infrastructure and in particular to **not** initialise it when the ELD code section is too small to contain the LINKCALL ELD. Another bug was that the multi-purpose and copyoutput puts handlers were not always entered with NC. This is not a problem in practice, but could be if a handler directly chained to its downlink rather than process the message. If it preserves the flags then [[https://hg.pushbx.org/ecm/ldebug/rev/3af67bd926a3|it should be entered with NC]] to let the message be written, in case the downlink consists of a branch back into the debugger. === Code return to ELD code section === The ''code_ret_to_ext'' function [[https://hg.pushbx.org/ecm/ldebug/rev/3dd1738a47ab|was adjusted to use the new dispatch mechanism]] next. (In the _PM=0 build this function is trivial as it consists of a single ''retf'' instruction.) === Entry to code section === A new function ''entry_to_code_segsel'' [[https://hg.pushbx.org/ecm/ldebug/rev/d16b28d98426|was added]], also using the new dispatch mechanism. This function [[https://hg.pushbx.org/ecm/ldebug/rev/19516417eac3|is now used in two places]]: To return from the entry section to the first code section and subsequently to the ELD code section, and to transfer from the entry section's interrupt return handler into the first code section. === ispm leaving NC === An unrelated change was [[https://hg.pushbx.org/ecm/ldebug/rev/651e547f084c|to add a comment]] indicating that ''ispm'' changes flags to NC, which the code already did. It wasn't documented for the _PM=0 replacement code however. (This replacement is a function consisting of only ''test sp, sp'' and ''retn''. It is assumed that our stack pointer can never be 0000h. The _PM=1 function already assumes we are running on our stack.) === eldtesth === To test the new entry via first code to ELD code path, I added the ''entry_retn'' function in serialp.asm which does nothing other than returning near. I [[https://hg.pushbx.org/ecm/ldebug/rev/1d4ec8129dd6|also added the code link to this function]], the first code link actually referencing section 2 (the entry section). Then [[https://hg.pushbx.org/ecm/ldebug/rev/5b9dd568341f|I created eldtesth.asm]] to try out calling into the entry section from an ELD. It worked flawlessly on the first attempt. === Dual call helpers === Next I adjusted the dispatch in the two _PM=1 dual call helpers ([[https://hg.pushbx.org/ecm/ldebug/rev/ad422cd8904f|1]], [[https://hg.pushbx.org/ecm/ldebug/rev/b4a17d100c21|2]], [[https://hg.pushbx.org/ecm/ldebug/rev/99d0034ff874|3]]). These are actually assembled into four helpers: One each for calling into the same code section as the caller, and one each for calling into the other code section. === Dual return helper === Next up was [[https://hg.pushbx.org/ecm/ldebug/rev/b6a554aa10da|the dual call return helper]]. This likewise is used only for _PM=1 builds and gets assembled twice, one per code section. This uses a small dispatch table to convert from the word values 1 or 0 to appropriate offsets from the ''code_seg'' variable. In practice, this entails multiplying by four. However, by using the table changing the flags is avoided so that ''pushf'' and ''popf'' can be dropped. === Near call helper for dual code === After that, [[https://hg.pushbx.org/ecm/ldebug/rev/4ca3e5ecf09b|the near call helper was next]]. This is used unless ''! _PM && _DUALCODENEARDUAL'' is true. For _PM=1 builds it is always used. For _PM=0 builds it is used only if near calls to the other section do not use per-function trampolines. (The default is to use the trampolines.) === DOS call === The ''_doscall_return_es'' and ''_doscall'' functions were adjusted next ([[https://hg.pushbx.org/ecm/ldebug/rev/c6e1130e0ba3|1]], [[https://hg.pushbx.org/ecm/ldebug/rev/f2c8807ade67|2]]). Like the ''transfer_ext_cx'' dispatch, these use a jump table. === Drop ax use in dual helpers === Finally, the use of the ''ax'' register [[https://hg.pushbx.org/ecm/ldebug/rev/1ac3ec4602fd|in several of the dual code helpers was avoided]], preferring to use ''bx'' and ''di'' only. ==== Message segsel retrieval ==== [[https://hg.pushbx.org/ecm/ldebug/rev/65c8a046dc71|A small change]] to the ''get_messagesegsel'' function optimises the _PM=1 build to always set ''ds'' to the selector value first, before testing for Protected Mode. ==== LINKCALL ELD can be allocated at nonzero offset ==== The debugger init was adjusted [[https://hg.pushbx.org/ecm/ldebug/rev/718a482337dc|to allow allocations]] before the LINKCALL ELD. This is normally never the case. To test the support, [[https://hg.pushbx.org/ecm/ldebug/rev/7d5c5eb0a39e|an option was added]] that does just such an allocation before allocating the LINKCALL ELD. {{tag>instsect ldosboot ldebug fddebug}} ~~DISCUSSION~~