User Tools

Site Tools


blog:pushbx:2022:0927_script_for_ldebug_sld_file_for_the_hp_95lx_and_more_ldebug_development

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

blog:pushbx:2022:0927_script_for_ldebug_sld_file_for_the_hp_95lx_and_more_ldebug_development [2022-09-27 20:00:24 +0200 Sep Tue] (current)
ecm created
Line 1: Line 1:
 +====== Script for lDebug (SLD) file for the HP 95LX, and more lDebug development ======
 +
 +**2022-09-25**
 +
 +Having adjusted the R, U, D, and E commands to be more 40-column friendly I am currently using the following script for lDebug (sld) file to set up the debugger:
 +
 +<code>r dco or= 800
 +r dco6 or= 1200
 +r dco2 or= 111
 +r ior = #16
 +r ioc = #40
 +r dao or= 80</code>
 +
 +===== =====
 +
 +  * DCO 800 instructs the debugger to use its own line editor, not the interrupt 21h service 0Ah line editor.
 +  * DCO6 200 makes the debugger do I/O to the ROM-BIOS terminal instead of the DOS one. This also allows to do register change highlighting using int 10h attributes instead of displaying ANSI escape sequences to the DOS terminal (which would require a driver).
 +  * DCO6 1000 is the 40-column friendly flag observed by R, U, D, E commands to change their output.
 +  * DCO2 111 enables the header line for all of the D commands, that is DB, DW, and DD. In 40-column friendly mode this header contains the segment being dumped, which is not displayed with the data dump in this mode.
 +  * IOR #16 sets the number of I/O Rows to 16, used by the paging. This matches the height of the visible screen of the 95LX.
 +  * IOC #40 sets the I/O Columns to 40, used by the debugger's line editor. Again this matches the width of the visible screen.
 +  * DAO 80 enables the use of the NEC V20 disassembly repeat rules. That means not only pop to ss and mov to ss cause repetition of the R command disassembly but also pop to ds or es and mov from or to any segment register.
 +
 +The script file is stored in A:\95LX.SLD. I run the debugger using a command like ''lcdebugu /d- /cy95lx.sld''. (I only transfer non-DPMI lCDebug builds to the 95LX because they can act both as the normal outer debugger or the inner debuggable debugger.)
 +
 +
 +**2022-09-26**
 +
 +I added one line to the 95LX.SLD script for lDebug file. I also created an alternative file which is useful for debugging filter style programs like unix2dos and b16cat. This is the full Q95LX.SLD file:
 +
 +<code>@r dco or= 800
 +@r dco6 or= 1200
 +r dco2 or= 111
 +r ior = #16
 +r ioc = #40
 +r dao or= 80
 +r dco3 and= ~ 4000_0000</code>
 +
 +This file is used in a command like ''lcdebugu.com /d- /c@yq95lx.sld''. The additional AT signs '@' insure that no output is written to the stdout DOS handle. After DCO6 flag 200 is set all further output of the debugger interface goes to the BIOS terminal so it won't interfere with the data sent to stdout.
 +
 +Clearing DCO3 flag 4000_0000 helps debugging a filter program, too. With this option set, the get key function's idle loop will also call interrupt 21h service 0Bh to make DOS check for Control-C. Unfortunately, it appears that this check sees the Control-C before our interrupt 16h calls get it. Therefore DOS writes "^C" to stdout and then cancels the debugger process. (The cancelling is fine, that is not a problem and works as intended.) This was observed as the ^C string missing when running with stdout redirected. It goes to stdout instead of the terminal. Clearing this DCO3 flag makes it so our interrupt 16h calls receive the Control-C keypress and we display "^C" to the terminal as intended.
 +
 +During debugging of this problem I created a memory image of the debugger's code segment and data segment. It went something like this:
 +
 +  * start lCDebug as ''A:\>lcdebugu /d- /cy95lx.sld lcdebugu.com /d+ /cy95lx.sld''
 +  * run a G command
 +  * in the debuggable debugger run a BU command
 +  * assemble on the stack of the debuggable debugger using an ''a ss:sp - 10'' command
 +    * assemble ''cmp al, 3'' \ ''jz (sp)''
 +  * search for the assembled instructions in the code segment using ''s cs:0 ffff range ss:sp - 10 l 3''
 +  * find the instance followed by a near immediate call (E8), this is the code checking for Control-C after displaying the "[more]" prompt
 +  * set a breakpoint several bytes prior where the getc function is called
 +  * set a breakpoint on the ''cmp al, 3'' instruction
 +  * run a G command to resume the debuggable debugger
 +  * run a long D command which will cause the "[more]" prompt to be displayed, returning control to the outer debugger
 +  * set up VF variable to point to an unused 128 KiB memory range
 +  * clear 64 KiB to all breakpoints using the command ''f vf:0 ffff cc''
 +  * enter the command ''re.replace @r; @r v0 ip; @r v1 abo - ip; @:loop; @r  byte [vf:v0] = byte [cs:v0]; @r v0 += 1; @r v1 -= 1; @if (v1) then goto :loop''
 +  * test RE commands using ''re'' command and examine memory with ''d vf:ip l 10''
 +  * run ''re.append @if (byte [cs:ip] == f4) then r dco2 or= 8000''
 +  * save data segment contents with ''m ss:0 ffff vf+1000:0''
 +  * run with ''tp fffff silent 1'' until control returns at a HLT instruction (can take several minutes)
 +  * run the long ''re.replace'' command again
 +  * run ''tp fffff silent 1'' again
 +  * this time press a key, eg Space bar, to make the run end at the breakpoint set on the ''cmp al, 3'' instruction (can take a minute or two)
 +  * run a G command
 +  * assemble a stub at VF:100
 +    * ''mov ax, cs''
 +    * ''add ax, 1000''
 +    * ''mov ds, ax''
 +    * ''mov es, ax''
 +    * ''mov ss, ax''
 +    * ''jmp'' to the offset of the first breakpoint, where the get key function is called
 +  * ''r bxcx = 20000 - 100''
 +  * ''n keyt2.bin''
 +  * ''w vf:100''
 +
 +Now you have a binary file that's nearly 128 KiB sized and should contain everything to trace execution until the keypress is received.
 +
 +
 +===== =====
 +
 +**Adjustments to the debugger**
 +
 +R: 16-bit display re-arranged to use 3 lines instead of 2, showing up to 5 of the 16-bit registers per line. Direction Flag and Interrupt Flag states are displayed as with one letter each.
 +
 +U: Mnemonic offset adjusted from 28 to 20, meaning only 4 bytes of machine code can be dumped per line (in a 16-bit code segment). Not perfect as long instructions can still exceed 40 columns. Jumping notices and referenced memory display still displayed up to 79th column.
 +
 +D: 8 bytes of data per line instead of 16. Segment is not displayed on data lines. All DB/DW/DD command outputs fit in 40 columns (for 16-bit segments). Segment is displayed in header and trailer, if those are enabled.
 +
 +E: After continuing interactive E mode by entering a blank, the prompt line will wrap around before any offset divisible by 4 intead of only divisible by 8. Output will not exceed 39 columns (in a 16-bit segment) except for when a byte with address modulo 4 equal to 3 is updated with two hexits and the update confirmed with a minus sign '-'.
 +
 +
 +{{tag>95lx ldebug}}
 +
 +
 +~~DISCUSSION~~
  
blog/pushbx/2022/0927_script_for_ldebug_sld_file_for_the_hp_95lx_and_more_ldebug_development.txt ยท Last modified: 2022-09-27 20:00:24 +0200 Sep Tue by ecm