An early use case I had for Extensions for lDebug was to run a tool like amitsrs. (This originates in Ralf Brown's AMIS libraries, for working with the Alternate Multiplex Interrupt Specification.) It is more detailed and heavyweight than I wanted to add as a command that lives internally in the debugger. I did consider possibly being able to compile the original C program's source to an ELD with bespoke libraries and output, but ultimately did not pursue this path further. (The differences are mainly that I/O must be done using the debugger links, and segmentation is very different and by default involves a linker that makes the offsets of the ELD data block and ELD code instance position-independent within their respective segments.)
Despite abandoning the C compiler, I did port amitsrs to become an ELD. This, then, simply involved porting the entire program to 8086 NASM assembly language. During testing this port, I found some bugs in the original program:
These bugs are fixed at least in a basic way by two changesets to my repo of amitsrs: 1 and 2. When adding support for displaying the hotkey list to amitsrs.eld, I based my work upon the fixed sources.
The zeroth order was to enable eldstrict mode in the ldmem.eld what was used as a basis.
The first order was to create a basic skeleton that has a no-op run function.
Next, the simple nonverbose output was implemented. This already required nontrivial string concatenation based on the "length" of the strings, which is folded into a simple printf
in the C sources. The work was made only slightly more difficult by juggling the segment/selector that points to the multiplexer's signatures. (To work in a bimodal way (Protected Mode or 86 Mode), the debugger's setes2dx
is used with the 86 Mode segment to obtain a usable seg/sel.) Unlike the C program, we do not need a near buffer to copy the signatures into. Also unlike the C program, we do use the line_out
buffer to build the output eventually sent to puts
, which is obscured by simply using printf
in the original. Like all subsequent porting steps, the C sources were copied into the assembly source file as comments. I left these in as comments behind the respective parts of the ported sources eventually.
The second line of the verbose display was fairly straightforward. I did have to use the debugger's dec_dword_minwidth
code link to replace the two-digit-minimum display of the minor version number.
Next up was the interrupt list display. This required more juggling of the Extra Segment register to access the multiplexer's interrupt list interleaved with using the debugger's code links. The offset into the interrupt list was kept in BX. The line-buffering again diverges from the original sources, in that up to three entries are buffered in line_out
until they are flushed to puts
. Using printf
is definitely easier to work with.
A small step in preparation for the next changeset was to make the next
label nonlocal, and put away the interrupts display into its own nonlocal label.
The final step in porting was to add the hotkey display. As mentioned, this was eventually based on the bugfixed revision of the original program. Some definitions from amis.h
were copied into the assembly language sources, and properly NASMified. (Use percent sign for %define
, do not double the backslash, comments with semicolons.) Again the 86 Mode segment, helpfully returned by the 86 Mode AMIS interface in a non-segment register, is fed to setes2dx
to address the multiplexer's hotkey list. The function to set up the Extra Segment was renamed to get_saved_es
, to indicate it is not used only for the interrupt list.
Two shift tables are used to loop through the various flags that can be set in the "required shift states" word. A last minute change was to split both tables into smaller sub-tables, as I found that some of the if
trees matching these flags actually involved else if
conditionals.
Other than that, there were some mmacros defined to convert the tables and if
ladders into readable assembly sources. shiftentry
accepts a numeric word as well as a message. scancodeentry
accepts only a message. dumpmessages
is used to write the messages saved by the two prior mmacros' calls, including their mmacro-local labels that these two mmacros use to refer to the messages.
The penultimate change was to add the credit for the original program to the assembly source file of the ELD.
Finally, the output of the ELD was changed to use trimputs
in two places. This actually changes the behaviour from the original C program, but is considered a feature rather than a bug. Both the "INT 09h " and "INT 15h " messages have trailing blanks in the ELD. Only one of those ("INT 09h ") has the trailing blanks in the C program, but if only this message is displayed then the trailing blanks won't be removed by the printf
powered output.
Further, if the description in the multiplexer's signatures is empty, the original program would display a trailing blank. This is also trimmed by the ELD.
The final trailing blank change is in the entry point display, which had a trailing blank for whatever reason. In the original program, all the way back to Ralf Brown's original release, there is an unconditional linebreak after this message has been written.
The amitsrs ELD at this point is fully compatible to the original (minus the trailing blanks). Moreover, it allows operation as an ELD installed residently, so it can even run while InDOS is set. Here's how the sizes of the XLD and ELD compare to the original's latest revision as compiled by gcc-ia16:
test$ ls -lgG total 48 -rwxr-xr-x 1 29034 Nov 14 23:40 amitsrs.com -rw-r--r-- 1 4720 Nov 14 23:49 amitsrs.eld -rw-r--r-- 1 4336 Nov 14 23:49 amitsrs.xld
The original is more than 5 times as large as the ELD! And that's with the ELD linker and resident installer and uninstaller contained in the ELD. Passing -O3
to the gcc-ia16 compiler helps a little, but not very much:
$ ./mak.sh -O3 $ ls -lgG amitsrs.com -rwxr-xr-x 1 27408 Nov 15 18:53 amitsrs.com
After reaching the fully compatible port, I changed the parsing for verbose mode to require an explicit "VERBOSE" keyword rather than just any non-empty parameter. At the same time, it now accepts the keywords "MPX", "HOTKEYS", or "INT" to select just one of the verbose outputs.
Next, the keywords moved into a table, except for "VERBOSE" which sets several flags. This simplified adding some alias keywords, "VERSION", "ENTRY", "KEYS", "INTLIST", "INTERRUPTS".
The ELD will probably also soon learn how to query and display only a specified range of multiplex numbers.