2023-01-29
This week little progress happened with any of the debuggers.
rr recently set up file transfers between a "Pofo" and some modern systems. I had him check running lDebug and lClock on there.
The debugger didn't fit in the default lCDebug build, uncompressed. I prepared a CDebug file with many of the build options disabled, such as the bootable mode, device driver mode, and the extended help. Some specific commands like DM, DI, X, RN, and D strings were also disabled.
Eventually I managed to create a CDebug build that requires less than 100 kB during installation, and about 84 kB once installed (plus the environment block). (It is called cdebug.com
without the L prefix because it is not bootable, building the application-mode-only shim executable.)
This build successfully runs on the Pofo.
lClock initially crashed the Pofo, even with its /D
switch (Demo mode). Using a CDebug dd 0:2D * 4 l 4
command we found that interrupt 2Dh had its vector initialised to an all-zeroes pointer. Moreover, interrupt 2Fh was also an all zeroes vector. This shows that the machine's DIP-DOS is closer to MS-DOS version 2 than version 3 in some ways.
I had extended lDebug a while ago to check for valid interrupts 2Dh and 2Fh before calling any of the services on these interrupts. But for the TSRs I have still been assuming MS-DOS v3 compatibility.
Rather than changing the TSRs, I created a small program (inst2d2f) to check for invalid vectors (segment all zeroes or offset all ones) and install a very small resident block (a single paragraph, in fact) which contains a single iret
instruction. If needed, this is installed as the interrupt 2Dh and/or 2Fh handler. This allows my TSRs to generally run at all.
Next problem was with the PSP relocation. Evidently, DIP-DOS stores the parent process or Parent Return Address at another spot than I expect for MS-DOS v2 and up compatibles. Trying to install the current lClock build resulted in a truncated message and then a return to the DOS prompt. (Quite likely this also permanently ate up memory used by the relocated process that never ran.)
Creating a build with the _PSPRELOC
build option set to zero resulted in installing the TSR successfully. However, it did not write a visible clock display (yet).
I advised rr to install lClock as lclock /s-
and to then use the debugger like this:
cdebug a mov ah, 00 ; multiplex number returned by installer mov al, 21 int 2D nop . r t t t dw dx:bx l 4
This should show the default two words of the lClock write pointer, reading the values 00A0h, B800h (or segmented far pointer B800h:00A0h). Note that the TSR writes to before this pointer, not starting at that position. So 00A0h, or 160, writes to the end of the first 80-column row, as there are two bytes per text cell.
By changing this pointer in the resident lClock and then running lclock /o /s+
the clock could be enabled and would then try to write at the changed position.
The adjustments possibly needed for the Pofo, as well as for the HP 95LX, are twofold: The text video buffer segment may be B000h instead of B800h. And the end of the first 80-column row may not be within the visible part of the virtual screen, requiring to scroll to see the clock display.
We did not yet manage to solve what segment and what offset is needed to successfully see the lClock display on the Pofo. However, rr reported that both segments appear to show the text mode video buffer contents. It is unclear if this means that writing to either would have the same effects.
I have been considering how to update Einsicht's disassembly and data dump views from lDebug. I did not yet get around to implementing any of those.
2023-01-30
The HP 95LX with its MS-DOS version 3.20 does not pose the interrupt vector or PSP relocation problems of the Pofo. However, its text video buffer is only accessible at segment B000h, not at lClock's default of segment B800h.
So this is how to make it work:
lclock /s- lcdebugu /d- /cy,95lx.sld a mov ah, 00 ; installed multiplex number mov al, 21 int 2D nop . r t t t dw dx:bx l 4 ; insure control data is correct (00A0, B800) d B000:0 l 8 lines ; check text screen buffer r word [dx:bx + 2] B000 r word [dx:bx] #40*2 + #80*2*9 q lclock /o /s+
Now the clock is visible in the top right corner of the screen. (However, when the visible screen is moved up it will be apparent that the clock leaves traces in the rows above the 10th virtual row.) Uninstall lClock again using lclock /r
.
I created a little script file which uses the debugger to issue a rename system call to the kernel, called rendeb.bat
. This is its content:
lcdebugu.com /c=e,200,\"%1\",0;e,300,\"%2\",0;a;"mov dx,200;mov di,300;mov ah,56;int 21;nop;.";t,4;r,f,.;r,ax,.;q
Note that it requires double-backslashes to pass along a single backslash to the DOS service, because the command line parsing of the debugger uses backslashes to escape other codepoints (like it does to pass along the double quote marks to the E commands).
2023-02-01
Also note that it is expected that the filenames passed to the batch script do not contain blanks, double quote marks, or semicolons (though they could be escaped to make that work). The length limit of 100h (256) bytes should suffice for any practical use. The scriptlet passed to the debugger writes the filenames to memory with a NUL terminator each, sets up the registers for the rename DOS service, and traces past the interrupt 21h call. Finally it depicts the current flags and value of ax
to pass error information to the user in case the service errors out.
Unlike the DOS shell's ren
command on this DOS version, the DOS kernel's rename service allows to rename across different directories on the same drive. That means that the rendeb.bat
script may come in handy if we ever need to move files across directories again.