189 lines
6.4 KiB
Text
189 lines
6.4 KiB
Text
Debugger in Emu48/Tools/Debugger...
|
||
-----------------------------------
|
||
|
||
This is a short description of the internal debugger of Emu48. The debugger is not perfect and/or complete. I provide it as it is. Please don't send me any suggestions or changes at the moment. If you have a better idea make it for yourself. Of course you're free to publish them or send me your changes.
|
||
|
||
The debugger was designed to help costumers inspecting assembler code objects, a part that cannot be handled satisfactorily by the JAZZ package. Thanks to Mika Heiskanen and all the others supporting this great program.
|
||
|
||
After starting the debugger the emulation will stop at the current PC position. The emulation will continue after closing the debugger window. Please remember that the clock now shows the wrong time.
|
||
|
||
|
||
1.) Menu Debug
|
||
|
||
- Run F5
|
||
|
||
Continue calculator emulation under debugger control. The emulation will stop at a breakpoint. Please remember that the emulation speed is slower than without debugger control.
|
||
|
||
- Step Into F7
|
||
|
||
Execute one code instruction.
|
||
|
||
- Step Over F8
|
||
|
||
Execute a GOSUB, GOSUBL or GOSBVL as one instruction. Normally the instruction cursor will set to the position behind the GOSUB instruction.
|
||
|
||
But this makes trouble in the following code part:
|
||
|
||
GOSUB +
|
||
NIBASC /Hello world/
|
||
+ C=RSTK
|
||
|
||
The program counter will never reach the address behind the GOSUB instruction. The debugger solve this problem by breaking the emulation when the stack has the same level before the GOSUB instruction. In this example the single step execution will continue after the C=RSTK instruction.
|
||
|
||
- Step Out F9
|
||
|
||
Continue the program until a RTI, RTN, RTNC, RTNCC, RTNNC, RTNSC, RTNSXN, RTNYES instruction is found above the current stack level.
|
||
|
||
At some code constructions (mostly used to save space on the hardware stack) like
|
||
|
||
C=RSTK
|
||
PC=C
|
||
|
||
and
|
||
|
||
C=RSTK
|
||
RSTK=C
|
||
RTN
|
||
|
||
the stop address will be wrong. The problem in both code fragments is the C=RSTK opcode. In the first example there is no RTN instruction to stop. In the second one the C=RSTK instruction purge the original return address and then the RSTK=C instruction is interpreted as a GOSUB instruction.
|
||
|
||
In opposite the following code will work fine:
|
||
|
||
RSTK=C
|
||
..
|
||
code <- F9 was pressed here
|
||
..
|
||
GOSUB -
|
||
C=RSTK
|
||
RTN <- emulation will stop after this instruction
|
||
- RTN
|
||
|
||
So be careful using the F9 key.
|
||
|
||
- Break F11
|
||
|
||
Stop the emulation started with F5.
|
||
|
||
|
||
2.) Menu Breakpoints
|
||
|
||
- Set breakpoint F2
|
||
|
||
Toggle a code breakpoint at the cursor position in the code window.
|
||
|
||
- Edit breakpoints...
|
||
|
||
You get a sorted list of the current code breakpoints. With "Add" you can add a new, with "Delete" you can delete an existing breakpoint. Addresses greater than #FFFFF are cutted after the fifths nibble.
|
||
|
||
- Clear all breakpoints
|
||
|
||
Clear all code breakpoints except the NOP3 ones.
|
||
|
||
- NOP3 code breakpoints
|
||
|
||
What are NOP3 code breakpoints? As you now user programs are loaded somewhere in memory and can be moved after a garbage collection. So it's very difficult to break a user program at a hard set breakpoint with F2. To solve this problem the debugger will stop emulation at a NOP3 opcode. So you can easily add a NOP3 command into your sources to force a break condition. To enable this you have to check this item.
|
||
|
||
NOP3 and NOP3, what's the difference? The Saturn CPU has no NOP command, so NOP3 is an opcode that is three nibbles long and doesn't change a register. In the HP SASM.DOC document two different opcodes are defined for NOP3:
|
||
|
||
Opcode 820 for HST=0 0
|
||
|
||
and
|
||
|
||
Opcode 420 for GOC + (next line)
|
||
|
||
In the assembler of the HPTOOLS 3.x package NOP3 is defined as opcode 820. The advantage of the opcode is that the execution time is always the same, independent from the carry flag. This code is used in the HP48 ROM as well. So I decided to use the GOC opcode for a code breakpoint condition.
|
||
|
||
A short example:
|
||
|
||
ASSEMBLE
|
||
NIBASC /HPHP48-E/
|
||
|
||
BREAK MACRO
|
||
CON(3) #024 NOP3
|
||
ENDM
|
||
|
||
RPL
|
||
CODE
|
||
BREAK code breakpoint
|
||
|
||
GOSBVL =SAVPTR save register
|
||
|
||
GOSUB + problem for step over
|
||
NIBASC /Hello world/
|
||
+ C=RSTK
|
||
|
||
GOVLNG =GETPTRLOOP
|
||
ENDCODE
|
||
|
||
|
||
3.) Code window
|
||
|
||
This windows shows you the disassembled code. The line with the current PC is marked with a "->" between the address and the disassembly.
|
||
|
||
You can use the UP, PAGE UP, DOWN and PAGE DOWN keys to scroll the window content. There is one strange behavior, when you move to higher addresses the debugger is able to disassemble the next line correctly, but when you move to cursor to lower addresses the debugger does not know if this address is at the begin or inside of an opcode. In result you get wrong disassembled lines.
|
||
|
||
Context menu pressing the right mouse button:
|
||
|
||
- Go to address... G
|
||
|
||
Moves the cursor to the specified code address.
|
||
|
||
- Go to PC
|
||
|
||
Sets the cursor to the actual position of the PC.
|
||
|
||
- Set breakpoint F2
|
||
|
||
Toggle a code breakpoint at the cursor position in the code window.
|
||
|
||
- Set PC to selection
|
||
|
||
Set the PC to the cursor position. Be careful with this command, you change the execution order of the commands!
|
||
|
||
|
||
4.) Register window
|
||
|
||
Here you can see the actual contents of the CPU registers. The values are only updated after a single step execution.
|
||
|
||
With the left mouse button you change the content of the register. On bit registers like CY and Mode the state changes immediately without any request.
|
||
|
||
|
||
5.) Memory window
|
||
|
||
This windows shows you the memory content.
|
||
|
||
You can use the arrow, PAGE UP and PAGE DOWN keys to move the cursor to a memory position. With a double click on the left mouse button you change the content of the two addresses. When the memory position is read only (ROM) the content wouldn't change.
|
||
|
||
Context menu pressing the right mouse button:
|
||
|
||
- Go to address... G
|
||
|
||
Moves the cursor to the specified memory address.
|
||
|
||
- Go to PC
|
||
|
||
Sets the cursor to the actual position of the PC.
|
||
|
||
- Go to D0
|
||
|
||
Sets the cursor to the actual position of the D0 register.
|
||
|
||
- Go to D1
|
||
|
||
Sets the cursor to the actual position of the D0 register.
|
||
|
||
- Go to Stack
|
||
|
||
Sets the cursor to the return address placed in the top level of the stack.
|
||
|
||
|
||
6.) Stack window
|
||
|
||
The content of the hardware stack is viewed here.
|
||
|
||
|
||
7.) Problems
|
||
|
||
The timers aren't updated in the single step mode at the moment. Please skip these parts with setting a code breakpoint behind the critical section and continue emulation with F5.
|
||
|
||
12/14/99 (c) by Christoph Gie<69>elink, cgiess@swol.de
|